aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2021-03-01 20:06:24 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2021-03-01 20:06:24 +0000
commitde67f49106fe22467c7617cae20264847a5a3606 (patch)
tree82d71322f724ed826e342e0ce19c0306256fa305
parent684f4e7212b4951b7e0d3888970a9fab53892344 (diff)
parentd29c5f8b3dd357bc7e369e7525cca42746a30b92 (diff)
downloadslirp-de67f49106fe22467c7617cae20264847a5a3606.zip
slirp-de67f49106fe22467c7617cae20264847a5a3606.tar.gz
slirp-de67f49106fe22467c7617cae20264847a5a3606.tar.bz2
Merge branch 'x_listen' into 'master'
Expose udpx_listen and tcpx_listen as taking sockaddr See merge request slirp/libslirp!74
-rw-r--r--src/socket.c96
-rw-r--r--src/socket.h4
-rw-r--r--src/udp.c77
-rw-r--r--src/udp.h6
4 files changed, 86 insertions, 97 deletions
diff --git a/src/socket.c b/src/socket.c
index d77b059..ff2d0d4 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -736,12 +736,11 @@ int sosendto(struct socket *so, struct mbuf *m)
/*
* Listen for incoming TCP connections
*/
-static struct socket *tcpx_listen(Slirp *slirp, int family,
- in4or6_addr haddr, unsigned hport,
- in4or6_addr laddr, unsigned lport,
- int flags)
+struct socket *tcpx_listen(Slirp *slirp,
+ union slirp_sockaddr *haddr, socklen_t haddrlen,
+ union slirp_sockaddr *laddr, socklen_t laddrlen,
+ int flags)
{
- union slirp_sockaddr addr;
struct socket *so;
int s, opt = 1;
socklen_t addrlen;
@@ -749,14 +748,16 @@ static struct socket *tcpx_listen(Slirp *slirp, int family,
DEBUG_CALL("tcpx_listen");
/* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */
char addrstr[INET6_ADDRSTRLEN];
- const char *str = inet_ntop(family, &haddr, addrstr, sizeof(addrstr));
- g_assert(str != NULL);
- DEBUG_ARG("haddr = %s", str);
- DEBUG_ARG("hport = %d", ntohs(hport));
- str = inet_ntop(family, &laddr, addrstr, sizeof(addrstr));
- g_assert(str != NULL);
- DEBUG_ARG("laddr = %s", str);
- DEBUG_ARG("lport = %d", ntohs(lport));
+ char portstr[6];
+ int ret;
+ ret = getnameinfo((struct sockaddr *) haddr, haddrlen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV);
+ g_assert(ret == 0);
+ DEBUG_ARG("haddr = %s", addrstr);
+ DEBUG_ARG("hport = %s", portstr);
+ ret = getnameinfo((struct sockaddr *) laddr, laddrlen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV);
+ g_assert(ret == 0);
+ DEBUG_ARG("laddr = %s", addrstr);
+ DEBUG_ARG("lport = %s", portstr);
DEBUG_ARG("flags = %x", flags);
so = socreate(slirp);
@@ -776,33 +777,12 @@ static struct socket *tcpx_listen(Slirp *slirp, int family,
so->so_state &= SS_PERSISTENT_MASK;
so->so_state |= (SS_FACCEPTCONN | flags);
- so->so_lfamily = family;
- /* Address,port are kept in network format */
- if (family == AF_INET) {
- so->so_laddr = laddr.addr4;
- so->so_lport = lport;
- } else {
- so->so_laddr6 = laddr.addr6;
- so->so_lport6 = lport;
- }
-
- memset(&addr, 0, sizeof(addr));
- if (family == AF_INET) {
- addr.sin.sin_family = family;
- addr.sin.sin_addr = haddr.addr4;
- addr.sin.sin_port = hport;
- addrlen = sizeof(addr.sin);
- } else {
- addr.sin6.sin6_family = family;
- addr.sin6.sin6_addr = haddr.addr6;
- addr.sin6.sin6_port = hport;
- addrlen = sizeof(addr.sin6);
- }
+ so->lhost = *laddr;
- s = slirp_socket(family, SOCK_STREAM, 0);
+ s = slirp_socket(haddr->ss.ss_family, SOCK_STREAM, 0);
if ((s < 0) ||
(slirp_socket_set_fast_reuse(s) < 0) ||
- (bind(s, (struct sockaddr *)&addr, addrlen) < 0) ||
+ (bind(s, (struct sockaddr *)haddr, haddrlen) < 0) ||
(listen(s, 1) < 0)) {
int tmperrno = errno; /* Don't clobber the real reason we failed */
if (s >= 0) {
@@ -820,39 +800,49 @@ static struct socket *tcpx_listen(Slirp *slirp, int family,
setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
slirp_socket_set_nodelay(s);
- getsockname(s, (struct sockaddr *)&addr, &addrlen);
- if (family == AF_INET) {
- so->fhost.sin = addr.sin;
- } else {
- so->fhost.sin6 = addr.sin6;
- }
+ addrlen = sizeof(so->fhost);
+ getsockname(s, (struct sockaddr *)&so->fhost, &addrlen);
sotranslate_accept(so);
so->s = s;
return so;
}
-/* TODO: rather fuse tcp_listen and tcp6_listen into tcp_listen that takes two
- * sockaddr */
struct socket *tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport,
uint32_t laddr, unsigned lport, int flags)
{
- in4or6_addr haddr4, laddr4;
+ struct sockaddr_in hsa, lsa;
+
+ memset(&hsa, 0, sizeof(hsa));
+ hsa.sin_family = AF_INET;
+ hsa.sin_addr.s_addr = haddr;
+ hsa.sin_port = hport;
- haddr4.addr4.s_addr = haddr;
- laddr4.addr4.s_addr = laddr;
- return tcpx_listen(slirp, AF_INET, haddr4, hport, laddr4, lport, flags);
+ memset(&lsa, 0, sizeof(lsa));
+ lsa.sin_family = AF_INET;
+ lsa.sin_addr.s_addr = laddr;
+ lsa.sin_port = lport;
+
+ return tcpx_listen(slirp, (union slirp_sockaddr*) &hsa, sizeof(hsa), (union slirp_sockaddr*) &lsa, sizeof(lsa), flags);
}
struct socket *
tcp6_listen(Slirp *slirp, struct in6_addr haddr, u_int hport,
struct in6_addr laddr, u_int lport, int flags)
{
- in4or6_addr haddr6, laddr6;
+ struct sockaddr_in6 hsa, lsa;
+
+ memset(&hsa, 0, sizeof(hsa));
+ hsa.sin6_family = AF_INET6;
+ hsa.sin6_addr = haddr;
+ hsa.sin6_port = hport;
+
+ memset(&lsa, 0, sizeof(lsa));
+ lsa.sin6_family = AF_INET6;
+ lsa.sin6_addr = laddr;
+ lsa.sin6_port = lport;
- haddr6.addr6 = haddr;
- laddr6.addr6 = laddr;
- return tcpx_listen(slirp, AF_INET6, haddr6, hport, laddr6, lport, flags);
+ return tcpx_listen(slirp, (union slirp_sockaddr*) &hsa, sizeof(hsa), (union slirp_sockaddr*) &lsa, sizeof(lsa), flags);
}
/*
diff --git a/src/socket.h b/src/socket.h
index 1a885a0..3a546fc 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -158,6 +158,10 @@ int sosendto(struct socket *, struct mbuf *);
struct socket *tcp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned, int);
struct socket *tcp6_listen(Slirp *, struct in6_addr, u_int,
struct in6_addr, u_int, int);
+struct socket *tcpx_listen(Slirp *slirp,
+ union slirp_sockaddr *haddr, socklen_t haddrlen,
+ union slirp_sockaddr *laddr, socklen_t laddrlen,
+ int flags);
void soisfconnecting(register struct socket *);
void soisfconnected(register struct socket *);
void sofwdrain(struct socket *);
diff --git a/src/udp.c b/src/udp.c
index 2b86c93..3b57d70 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -353,17 +353,16 @@ static uint8_t udp_tos(struct socket *so)
return 0;
}
-static struct socket *udpx_listen(Slirp *slirp, int family,
- in4or6_addr haddr, unsigned hport,
- in4or6_addr laddr, unsigned lport,
- int flags)
+struct socket *udpx_listen(Slirp *slirp,
+ union slirp_sockaddr *haddr, socklen_t haddrlen,
+ union slirp_sockaddr *laddr, socklen_t laddrlen,
+ int flags)
{
- union slirp_sockaddr addr;
struct socket *so;
socklen_t addrlen;
so = socreate(slirp);
- so->s = slirp_socket(family, SOCK_DGRAM, 0);
+ so->s = slirp_socket(haddr->ss.ss_family, SOCK_DGRAM, 0);
if (so->s < 0) {
sofree(so);
return NULL;
@@ -371,41 +370,17 @@ static struct socket *udpx_listen(Slirp *slirp, int family,
so->so_expire = curtime + SO_EXPIRE;
insque(so, &slirp->udb);
- memset(&addr, 0, sizeof(addr));
- if (family == AF_INET) {
- addr.sin.sin_family = family;
- addr.sin.sin_addr = haddr.addr4;
- addr.sin.sin_port = hport;
- addrlen = sizeof(addr.sin);
- } else {
- addr.sin6.sin6_family = family;
- addr.sin6.sin6_addr = haddr.addr6;
- addr.sin6.sin6_port = hport;
- addrlen = sizeof(addr.sin6);
- }
-
- if (bind(so->s, (struct sockaddr *)&addr, addrlen) < 0) {
+ if (bind(so->s, (struct sockaddr *)haddr, haddrlen) < 0) {
udp_detach(so);
return NULL;
}
slirp_socket_set_fast_reuse(so->s);
- getsockname(so->s, (struct sockaddr *)&addr, &addrlen);
- if (family == AF_INET) {
- so->fhost.sin = addr.sin;
- } else {
- so->fhost.sin6 = addr.sin6;
- }
+ addrlen = sizeof(so->fhost);
+ getsockname(so->s, (struct sockaddr *)&so->fhost, &addrlen);
sotranslate_accept(so);
- so->so_lfamily = family;
- if (family == AF_INET) {
- so->so_laddr = laddr.addr4;
- so->so_lport = lport;
- } else {
- so->so_laddr6 = laddr.addr6;
- so->so_lport6 = lport;
- }
+ so->lhost = *laddr;
if (flags != SS_FACCEPTONCE)
so->so_expire = 0;
@@ -415,25 +390,39 @@ static struct socket *udpx_listen(Slirp *slirp, int family,
return so;
}
-/* TODO: rather fuse udp_listen and udp6_listen into udp_listen that takes two
- * sockaddr */
struct socket *udp_listen(Slirp *slirp, uint32_t haddr, unsigned hport,
uint32_t laddr, unsigned lport, int flags)
{
- in4or6_addr haddr4, laddr4;
+ struct sockaddr_in hsa, lsa;
- haddr4.addr4.s_addr = haddr;
- laddr4.addr4.s_addr = laddr;
- return udpx_listen(slirp, AF_INET, haddr4, hport, laddr4, lport, flags);
+ memset(&hsa, 0, sizeof(hsa));
+ hsa.sin_family = AF_INET;
+ hsa.sin_addr.s_addr = haddr;
+ hsa.sin_port = hport;
+
+ memset(&lsa, 0, sizeof(lsa));
+ lsa.sin_family = AF_INET;
+ lsa.sin_addr.s_addr = laddr;
+ lsa.sin_port = lport;
+
+ return udpx_listen(slirp, (union slirp_sockaddr*) &hsa, sizeof(hsa), (union slirp_sockaddr*) &lsa, sizeof(lsa), flags);
}
struct socket *
udp6_listen(Slirp *slirp, struct in6_addr haddr, u_int hport,
struct in6_addr laddr, u_int lport, int flags)
{
- in4or6_addr haddr6, laddr6;
+ struct sockaddr_in6 hsa, lsa;
+
+ memset(&hsa, 0, sizeof(hsa));
+ hsa.sin6_family = AF_INET6;
+ hsa.sin6_addr = haddr;
+ hsa.sin6_port = hport;
+
+ memset(&lsa, 0, sizeof(lsa));
+ lsa.sin6_family = AF_INET6;
+ lsa.sin6_addr = laddr;
+ lsa.sin6_port = lport;
- haddr6.addr6 = haddr;
- laddr6.addr6 = laddr;
- return udpx_listen(slirp, AF_INET6, haddr6, hport, laddr6, lport, flags);
+ return udpx_listen(slirp, (union slirp_sockaddr*) &hsa, sizeof(hsa), (union slirp_sockaddr*) &lsa, sizeof(lsa), flags);
}
diff --git a/src/udp.h b/src/udp.h
index b3fbeac..5361c2b 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -34,6 +34,8 @@
#ifndef UDP_H
#define UDP_H
+#include "socket.h"
+
#define UDP_TTL 0x60
#define UDP_UDPDATALEN 16192
@@ -82,6 +84,10 @@ void udp_detach(struct socket *);
struct socket *udp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned, int);
struct socket *udp6_listen(Slirp *slirp, struct in6_addr, u_int,
struct in6_addr, u_int, int);
+struct socket *udpx_listen(Slirp *,
+ union slirp_sockaddr *haddr, socklen_t haddrlen,
+ union slirp_sockaddr *laddr, socklen_t laddrlen,
+ int flags);
int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr,
struct sockaddr_in *daddr, int iptos);