|
|
|
|
@ -23,12 +23,6 @@ static bool __ip4_eq(const sockaddr_t *a, const sockaddr_t *b);
|
|
|
|
|
static bool __ip6_eq(const sockaddr_t *a, const sockaddr_t *b);
|
|
|
|
|
static bool __ip4_is_specified(const sockaddr_t *a);
|
|
|
|
|
static bool __ip6_is_specified(const sockaddr_t *a);
|
|
|
|
|
static bool __ip_bind(socket_t *s, unsigned int, const sockaddr_t *);
|
|
|
|
|
static bool __ip_connect(socket_t *s, const endpoint_t *);
|
|
|
|
|
static bool __ip_listen(socket_t *s, int backlog);
|
|
|
|
|
static bool __ip_accept(socket_t *s, socket_t *new_sock);
|
|
|
|
|
static bool __ip_getsockname(socket_t *s);
|
|
|
|
|
static bool __ip_timestamping(socket_t *s);
|
|
|
|
|
static bool __ip4_pktinfo(socket_t *s);
|
|
|
|
|
static bool __ip6_pktinfo(socket_t *s);
|
|
|
|
|
static bool __ip4_sockaddr2endpoint(endpoint_t *, const void *);
|
|
|
|
|
@ -37,15 +31,10 @@ static bool __ip4_endpoint2sockaddr(void *, const endpoint_t *);
|
|
|
|
|
static bool __ip6_endpoint2sockaddr(void *, const endpoint_t *);
|
|
|
|
|
static bool __ip4_addrport2sockaddr(void *, const sockaddr_t *, unsigned int);
|
|
|
|
|
static bool __ip6_addrport2sockaddr(void *, const sockaddr_t *, unsigned int);
|
|
|
|
|
static ssize_t __ip_recvfrom(socket_t *s, void *buf, size_t len, endpoint_t *ep);
|
|
|
|
|
static ssize_t __ip_recvfrom_ts(socket_t *s, void *buf, size_t len, endpoint_t *ep, int64_t *);
|
|
|
|
|
static ssize_t __ip4_recvfrom_to(socket_t *s, void *buf, size_t len, endpoint_t *ep, sockaddr_t *to);
|
|
|
|
|
static ssize_t __ip6_recvfrom_to(socket_t *s, void *buf, size_t len, endpoint_t *ep, sockaddr_t *to);
|
|
|
|
|
static ssize_t __ip_sendmsg(socket_t *s, struct msghdr *mh, const endpoint_t *ep);
|
|
|
|
|
static ssize_t __ip_sendto(socket_t *s, const void *buf, size_t len, const endpoint_t *ep);
|
|
|
|
|
static bool __ip4_tos(socket_t *, unsigned int);
|
|
|
|
|
static bool __ip6_tos(socket_t *, unsigned int);
|
|
|
|
|
static int __ip_error(socket_t *s);
|
|
|
|
|
static void __ip4_pmtu_disc(socket_t *, int);
|
|
|
|
|
static void __ip4_endpoint2kernel(struct re_address *, const endpoint_t *);
|
|
|
|
|
static void __ip6_endpoint2kernel(struct re_address *, const endpoint_t *);
|
|
|
|
|
@ -84,20 +73,9 @@ static struct socket_family __socket_families[__SF_LAST] = {
|
|
|
|
|
.sockaddr2endpoint = __ip4_sockaddr2endpoint,
|
|
|
|
|
.endpoint2sockaddr = __ip4_endpoint2sockaddr,
|
|
|
|
|
.addrport2sockaddr = __ip4_addrport2sockaddr,
|
|
|
|
|
.bind = __ip_bind,
|
|
|
|
|
.connect = __ip_connect,
|
|
|
|
|
.listen = __ip_listen,
|
|
|
|
|
.accept = __ip_accept,
|
|
|
|
|
.getsockname = __ip_getsockname,
|
|
|
|
|
.timestamping = __ip_timestamping,
|
|
|
|
|
.pktinfo = __ip4_pktinfo,
|
|
|
|
|
.recvfrom = __ip_recvfrom,
|
|
|
|
|
.recvfrom_ts = __ip_recvfrom_ts,
|
|
|
|
|
.recvfrom_to = __ip4_recvfrom_to,
|
|
|
|
|
.sendmsg = __ip_sendmsg,
|
|
|
|
|
.sendto = __ip_sendto,
|
|
|
|
|
.tos = __ip4_tos,
|
|
|
|
|
.error = __ip_error,
|
|
|
|
|
.pmtu_disc = __ip4_pmtu_disc,
|
|
|
|
|
.endpoint2kernel = __ip4_endpoint2kernel,
|
|
|
|
|
.kernel2endpoint = __ip4_kernel2endpoint,
|
|
|
|
|
@ -120,20 +98,9 @@ static struct socket_family __socket_families[__SF_LAST] = {
|
|
|
|
|
.sockaddr2endpoint = __ip6_sockaddr2endpoint,
|
|
|
|
|
.endpoint2sockaddr = __ip6_endpoint2sockaddr,
|
|
|
|
|
.addrport2sockaddr = __ip6_addrport2sockaddr,
|
|
|
|
|
.bind = __ip_bind,
|
|
|
|
|
.connect = __ip_connect,
|
|
|
|
|
.listen = __ip_listen,
|
|
|
|
|
.accept = __ip_accept,
|
|
|
|
|
.getsockname = __ip_getsockname,
|
|
|
|
|
.timestamping = __ip_timestamping,
|
|
|
|
|
.pktinfo = __ip6_pktinfo,
|
|
|
|
|
.recvfrom = __ip_recvfrom,
|
|
|
|
|
.recvfrom_ts = __ip_recvfrom_ts,
|
|
|
|
|
.recvfrom_to = __ip6_recvfrom_to,
|
|
|
|
|
.sendmsg = __ip_sendmsg,
|
|
|
|
|
.sendto = __ip_sendto,
|
|
|
|
|
.tos = __ip6_tos,
|
|
|
|
|
.error = __ip_error,
|
|
|
|
|
.endpoint2kernel = __ip6_endpoint2kernel,
|
|
|
|
|
.kernel2endpoint = __ip6_kernel2endpoint,
|
|
|
|
|
.packet_header = __ip6_packet_header,
|
|
|
|
|
@ -267,7 +234,7 @@ static bool __ip6_addrport2sockaddr(void *p, const sockaddr_t *sa, unsigned int
|
|
|
|
|
sin->sin6_addr = sa->ipv6;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
static bool __ip_bind(socket_t *s, unsigned int port, const sockaddr_t *a) {
|
|
|
|
|
bool socket_bind(socket_t *s, unsigned int port, const sockaddr_t *a) {
|
|
|
|
|
struct sockaddr_storage sin;
|
|
|
|
|
|
|
|
|
|
s->family->addrport2sockaddr(&sin, a, port);
|
|
|
|
|
@ -280,7 +247,7 @@ static bool __ip_bind(socket_t *s, unsigned int port, const sockaddr_t *a) {
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
static bool __ip_connect(socket_t *s, const endpoint_t *ep) {
|
|
|
|
|
bool socket_connect(socket_t *s, const endpoint_t *ep) {
|
|
|
|
|
struct sockaddr_storage sin;
|
|
|
|
|
|
|
|
|
|
s->family->endpoint2sockaddr(&sin, ep);
|
|
|
|
|
@ -292,10 +259,7 @@ static bool __ip_connect(socket_t *s, const endpoint_t *ep) {
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
static bool __ip_listen(socket_t *s, int backlog) {
|
|
|
|
|
return listen(s->fd, backlog) == 0;
|
|
|
|
|
}
|
|
|
|
|
static bool __ip_accept(socket_t *s, socket_t *newsock) {
|
|
|
|
|
bool socket_accept(socket_t *s, socket_t *newsock) {
|
|
|
|
|
int nfd;
|
|
|
|
|
struct sockaddr_storage sin;
|
|
|
|
|
socklen_t sinlen;
|
|
|
|
|
@ -316,7 +280,7 @@ static bool __ip_accept(socket_t *s, socket_t *newsock) {
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
static bool __ip_getsockname(socket_t *s) {
|
|
|
|
|
bool socket_getsockname(socket_t *s) {
|
|
|
|
|
struct sockaddr_storage sin;
|
|
|
|
|
socklen_t sinlen = sizeof(sin);
|
|
|
|
|
int ret = getsockname(s->fd, (struct sockaddr *) &sin, &sinlen);
|
|
|
|
|
@ -358,10 +322,10 @@ INLINE ssize_t __ip_recvfrom_options(socket_t *s, void *buf, size_t len, endpoin
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
static ssize_t __ip_recvfrom_ts(socket_t *s, void *buf, size_t len, endpoint_t *ep, int64_t *tv) {
|
|
|
|
|
ssize_t socket_recvfrom_ts(socket_t *s, void *buf, size_t len, endpoint_t *ep, int64_t *tv) {
|
|
|
|
|
return __ip_recvfrom_options(s, buf, len, ep, tv, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
static ssize_t __ip_recvfrom(socket_t *s, void *buf, size_t len, endpoint_t *ep) {
|
|
|
|
|
ssize_t socket_recvfrom(socket_t *s, void *buf, size_t len, endpoint_t *ep) {
|
|
|
|
|
return __ip_recvfrom_options(s, buf, len, ep, NULL, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
INLINE bool __ip4_pktinfo_parse(struct cmsghdr *cm, sockaddr_t *to) {
|
|
|
|
|
@ -386,7 +350,7 @@ static ssize_t __ip4_recvfrom_to(socket_t *s, void *buf, size_t len, endpoint_t
|
|
|
|
|
static ssize_t __ip6_recvfrom_to(socket_t *s, void *buf, size_t len, endpoint_t *ep, sockaddr_t *to) {
|
|
|
|
|
return __ip_recvfrom_options(s, buf, len, ep, NULL, to, __ip6_pktinfo_parse);
|
|
|
|
|
}
|
|
|
|
|
static ssize_t __ip_sendmsg(socket_t *s, struct msghdr *mh, const endpoint_t *ep) {
|
|
|
|
|
ssize_t socket_sendmsg(socket_t *s, struct msghdr *mh, const endpoint_t *ep) {
|
|
|
|
|
struct sockaddr_storage sin;
|
|
|
|
|
|
|
|
|
|
if (ep) {
|
|
|
|
|
@ -397,7 +361,7 @@ static ssize_t __ip_sendmsg(socket_t *s, struct msghdr *mh, const endpoint_t *ep
|
|
|
|
|
|
|
|
|
|
return sendmsg(s->fd, mh, 0);
|
|
|
|
|
}
|
|
|
|
|
static ssize_t __ip_sendto(socket_t *s, const void *buf, size_t len, const endpoint_t *ep) {
|
|
|
|
|
ssize_t socket_sendto(socket_t *s, const void *buf, size_t len, const endpoint_t *ep) {
|
|
|
|
|
struct sockaddr_storage sin;
|
|
|
|
|
|
|
|
|
|
if (!ep->address.family)
|
|
|
|
|
@ -417,7 +381,7 @@ static bool __ip6_tos(socket_t *s, unsigned int tos) {
|
|
|
|
|
ilog(LOG_ERR, "Failed to set TOS on IPv6 socket: %s", strerror(errno));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
static int __ip_error(socket_t *s) {
|
|
|
|
|
int socket_error(socket_t *s) {
|
|
|
|
|
int optval;
|
|
|
|
|
socklen_t optlen = sizeof(optval);
|
|
|
|
|
if (getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &optval, &optlen))
|
|
|
|
|
@ -428,7 +392,7 @@ static void __ip4_pmtu_disc(socket_t *s, int opt) {
|
|
|
|
|
if (setsockopt(s->fd, IPPROTO_IP, IP_MTU_DISCOVER, &opt, sizeof(opt)))
|
|
|
|
|
ilog(LOG_ERR, "Failed to set PMTU discovery option on IPv4 socket: %s", strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
static bool __ip_timestamping(socket_t *s) {
|
|
|
|
|
bool socket_timestamping(socket_t *s) {
|
|
|
|
|
int one = 1;
|
|
|
|
|
if (setsockopt(s->fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)))
|
|
|
|
|
return false;
|
|
|
|
|
@ -783,7 +747,7 @@ bool open_socket(socket_t *r, int type, unsigned int port, const sockaddr_t *sa)
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!fam->bind(r, port, sa)) {
|
|
|
|
|
if (!socket_bind(r, port, sa)) {
|
|
|
|
|
dbg_int("open socket fail, fd=%d, port=%d", r->fd, port);
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
@ -833,7 +797,7 @@ bool connect_socket(socket_t *r, int type, const endpoint_t *ep) {
|
|
|
|
|
|
|
|
|
|
if (!__socket(r, type, fam))
|
|
|
|
|
return false;
|
|
|
|
|
if (!fam->connect(r, ep))
|
|
|
|
|
if (!socket_connect(r, ep))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
r->remote = *ep;
|
|
|
|
|
@ -848,7 +812,7 @@ fail:
|
|
|
|
|
int connect_socket_retry(socket_t *r) {
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (!r->family->connect(r, &r->remote)) {
|
|
|
|
|
if (!socket_connect(r, &r->remote)) {
|
|
|
|
|
if (errno != EINPROGRESS && errno != EALREADY && errno != EISCONN)
|
|
|
|
|
goto fail;
|
|
|
|
|
if (errno != EISCONN)
|
|
|
|
|
|