diff --git a/mdp_client.c b/mdp_client.c index 3db4ca9f..cb0459d3 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -43,10 +43,10 @@ static void mdp_unlink(int mdp_sock) if (getsockname(mdp_sock, &addr.addr, &addr.addrlen)) WHYF_perror("getsockname(%d)", mdp_sock); else if (addr.addr.sa_family==AF_UNIX - && addr.addrlen > sizeof addr.addr_un.sun_family - && addr.addrlen <= sizeof addr.addr_un && addr.addr_un.sun_path[0] != '\0') { - if (unlink(addr.addr_un.sun_path) == -1) - WARNF_perror("unlink(%s)", alloca_str_toprint(addr.addr_un.sun_path)); + && addr.addrlen > sizeof addr.local.sun_family + && addr.addrlen <= sizeof addr.local && addr.local.sun_path[0] != '\0') { + if (unlink(addr.local.sun_path) == -1) + WARNF_perror("unlink(%s)", alloca_str_toprint(addr.local.sun_path)); } close(mdp_sock); } @@ -123,7 +123,7 @@ ssize_t mdp_recv(int socket, struct mdp_header *header, uint8_t *payload, ssize_ addr.addrlen=hdr.msg_namelen; // double check that the incoming address matches the servald daemon if (cmp_sockaddr(&addr, &mdp_addr) != 0 - && ( addr.addr_un.sun_family != AF_UNIX + && ( addr.local.sun_family != AF_UNIX || real_sockaddr(&addr, &addr) <= 0 || cmp_sockaddr(&addr, &mdp_addr) != 0 ) @@ -259,7 +259,7 @@ int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, mdp_port_t port, in ssize_t len; mdp->packetTypeAndFlags = 0; set_nonblock(mdp_sockfd); - len = recvwithttl(mdp_sockfd, (unsigned char *)mdp, sizeof(overlay_mdp_frame), ttl, &recvaddr.addr, &recvaddr.addrlen); + len = recvwithttl(mdp_sockfd, (unsigned char *)mdp, sizeof(overlay_mdp_frame), ttl, &recvaddr); set_block(mdp_sockfd); if (len <= 0) return -1; // no packet received @@ -272,7 +272,7 @@ int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, mdp_port_t port, in // Compare the address of the sender with the address of our server, to ensure they are the same. // If the comparison fails, then try using realpath(3) on the sender address and compare again. if ( cmp_sockaddr(&recvaddr, &mdp_addr) != 0 - && ( recvaddr.addr_un.sun_family != AF_UNIX + && ( recvaddr.local.sun_family != AF_UNIX || real_sockaddr(&recvaddr, &recvaddr) <= 0 || cmp_sockaddr(&recvaddr, &mdp_addr) != 0 ) diff --git a/net.c b/net.c index e5e2da00..ec622ec0 100644 --- a/net.c +++ b/net.c @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "serval.h" #include "conf.h" #include "net.h" +#include "socket.h" #include "str.h" #include "strbuf_helpers.h" @@ -138,8 +139,7 @@ ssize_t _write_str_nonblock(int fd, const char *str, struct __sourceloc __whence return _write_all_nonblock(fd, str, strlen(str), __whence); } -ssize_t recvwithttl(int sock,unsigned char *buffer, size_t bufferlen,int *ttl, - struct sockaddr *recvaddr, socklen_t *recvaddrlen) +ssize_t recvwithttl(int sock,unsigned char *buffer, size_t bufferlen,int *ttl, struct socket_address *recvaddr) { struct msghdr msg; struct iovec iov[1]; @@ -147,8 +147,8 @@ ssize_t recvwithttl(int sock,unsigned char *buffer, size_t bufferlen,int *ttl, iov[0].iov_base=buffer; iov[0].iov_len=bufferlen; bzero(&msg,sizeof(msg)); - msg.msg_name = recvaddr; - msg.msg_namelen = *recvaddrlen; + msg.msg_name = &recvaddr->store; + msg.msg_namelen = recvaddr->addrlen; msg.msg_iov = &iov[0]; msg.msg_iovlen = 1; // setting the following makes the data end up in the wrong place @@ -192,7 +192,7 @@ ssize_t recvwithttl(int sock,unsigned char *buffer, size_t bufferlen,int *ttl, } } } - *recvaddrlen=msg.msg_namelen; + recvaddr->addrlen = msg.msg_namelen; return len; } diff --git a/net.h b/net.h index 108b3f56..6ef3e1c0 100644 --- a/net.h +++ b/net.h @@ -52,6 +52,8 @@ ssize_t _write_all_nonblock(int fd, const void *buf, size_t len, struct __source ssize_t _writev_all(int fd, const struct iovec *iov, int iovcnt, struct __sourceloc __whence); ssize_t _write_str(int fd, const char *str, struct __sourceloc __whence); ssize_t _write_str_nonblock(int fd, const char *str, struct __sourceloc __whence); -ssize_t recvwithttl(int sock, unsigned char *buffer, size_t bufferlen, int *ttl, struct sockaddr *recvaddr, socklen_t *recvaddrlen); + +struct socket_address; +ssize_t recvwithttl(int sock, unsigned char *buffer, size_t bufferlen, int *ttl, struct socket_address *); #endif // __SERVALD_NET_H diff --git a/overlay_interface.c b/overlay_interface.c index 48e96c91..9568c992 100644 --- a/overlay_interface.c +++ b/overlay_interface.c @@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include "serval.h" #include "conf.h" +#include "net.h" +#include "socket.h" #include "strbuf.h" #include "strbuf_helpers.h" #include "overlay_buffer.h" @@ -248,18 +250,19 @@ int overlay_interface_compare(overlay_interface *one, overlay_interface *two) // OSX doesn't recieve broadcast packets on sockets bound to an interface's address // So we have to bind a socket to INADDR_ANY to receive these packets. static void -overlay_interface_read_any(struct sched_ent *alarm){ +overlay_interface_read_any(struct sched_ent *alarm) +{ if (alarm->poll.revents & POLLIN) { int plen=0; int recvttl=1; unsigned char packet[16384]; overlay_interface *interface=NULL; - struct sockaddr src_addr; - socklen_t addrlen = sizeof(src_addr); + struct socket_address recvaddr; + recvaddr.addrlen = sizeof recvaddr.store; /* Read only one UDP packet per call to share resources more fairly, and also enable stats to accurately count packets received */ - plen = recvwithttl(alarm->poll.fd, packet, sizeof(packet), &recvttl, &src_addr, &addrlen); + plen = recvwithttl(alarm->poll.fd, packet, sizeof(packet), &recvttl, &recvaddr); if (plen == -1) { WHY_perror("recvwithttl(c)"); unwatch(alarm); @@ -267,18 +270,16 @@ overlay_interface_read_any(struct sched_ent *alarm){ return; } - struct in_addr src = ((struct sockaddr_in *)&src_addr)->sin_addr; - /* Try to identify the real interface that the packet arrived on */ - interface = overlay_interface_find(src, 0); + interface = overlay_interface_find(recvaddr.inet.sin_addr, 0); /* Drop the packet if we don't find a match */ if (!interface){ if (config.debug.overlayinterfaces) - DEBUGF("Could not find matching interface for packet received from %s", inet_ntoa(src)); + DEBUGF("Could not find matching interface for packet received from %s", inet_ntoa(recvaddr.inet.sin_addr)); return; } - packetOkOverlay(interface, packet, plen, recvttl, &src_addr, addrlen); + packetOkOverlay(interface, packet, plen, recvttl, &recvaddr); } if (alarm->poll.revents & (POLLHUP | POLLERR)) { INFO("Closing broadcast socket due to error"); @@ -569,25 +570,24 @@ cleanup: return cleanup_ret; } -static void interface_read_dgram(struct overlay_interface *interface){ +static void interface_read_dgram(struct overlay_interface *interface) +{ int plen=0; unsigned char packet[8096]; - struct sockaddr src_addr; - socklen_t addrlen = sizeof(src_addr); - - + struct socket_address recvaddr; + recvaddr.addrlen = sizeof recvaddr.store; + /* Read only one UDP packet per call to share resources more fairly, and also enable stats to accurately count packets received */ int recvttl=1; - plen = recvwithttl(interface->alarm.poll.fd,packet, sizeof(packet), &recvttl, &src_addr, &addrlen); + plen = recvwithttl(interface->alarm.poll.fd,packet, sizeof(packet), &recvttl, &recvaddr); if (plen == -1) { WHY_perror("recvwithttl(c)"); overlay_interface_close(interface); return; } - - packetOkOverlay(interface, packet, plen, recvttl, &src_addr, addrlen); + packetOkOverlay(interface, packet, plen, recvttl, &recvaddr); } struct file_packet{ @@ -678,8 +678,10 @@ static void interface_read_file(struct overlay_interface *interface) alloca_sockaddr_in(&packet.dst_addr) ); }else{ - packetOkOverlay(interface, packet.payload, packet.payload_length, -1, - (struct sockaddr*)&packet.src_addr, (socklen_t) sizeof(packet.src_addr)); + struct socket_address srcaddr; + srcaddr.addrlen = sizeof packet.src_addr; + srcaddr.inet = packet.src_addr; + packetOkOverlay(interface, packet.payload, packet.payload_length, -1, &srcaddr); } } } diff --git a/overlay_mdp.c b/overlay_mdp.c index 72652a8e..4f570bc0 100644 --- a/overlay_mdp.c +++ b/overlay_mdp.c @@ -1479,11 +1479,11 @@ static void overlay_mdp_poll(struct sched_ent *alarm) unsigned char buffer[16384]; int ttl; struct socket_address client; - client.addrlen=sizeof(client.store); + client.addrlen = sizeof client.store; ttl=-1; - ssize_t len = recvwithttl(alarm->poll.fd,buffer,sizeof(buffer),&ttl, (struct sockaddr *)&client.addr, &client.addrlen); + ssize_t len = recvwithttl(alarm->poll.fd,buffer,sizeof(buffer),&ttl, &client); if (len > 0) { if (client.addrlen <= sizeof(sa_family_t)) diff --git a/overlay_packetformats.c b/overlay_packetformats.c index c2c39208..b9261e05 100644 --- a/overlay_packetformats.c +++ b/overlay_packetformats.c @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "serval.h" #include "conf.h" +#include "socket.h" #include "str.h" #include "strbuf.h" #include "overlay_buffer.h" @@ -320,7 +321,7 @@ int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface } int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, size_t len, - int recvttl, struct sockaddr *recvaddr, socklen_t recvaddrlen) + int recvttl, struct socket_address *recvaddr) { IN(); /* @@ -385,8 +386,8 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s } } - if (recvaddr&&recvaddr->sa_family!=AF_INET) - RETURN(WHYF("Unexpected protocol family %d",recvaddr->sa_family)); + if (recvaddr && recvaddr->addr.sa_family != AF_INET) + RETURN(WHYF("Unexpected protocol family %d", recvaddr->addr.sa_family)); struct overlay_frame f; struct decode_context context; @@ -399,11 +400,11 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s f.interface = interface; if (recvaddr) - f.recvaddr = *((struct sockaddr_in *)recvaddr); + f.recvaddr = recvaddr->inet; else bzero(&f.recvaddr, sizeof f.recvaddr); - int ret=parseEnvelopeHeader(&context, interface, (struct sockaddr_in *)recvaddr, b); + int ret=parseEnvelopeHeader(&context, interface, recvaddr ? &recvaddr->inet : NULL, b); if (ret){ ob_free(b); RETURN(ret); diff --git a/radio_link.c b/radio_link.c index 628a4bf9..2b2f9224 100644 --- a/radio_link.c +++ b/radio_link.c @@ -433,7 +433,7 @@ static int radio_link_parse(struct overlay_interface *interface, struct radio_li if (config.debug.radio_link) DEBUGF("PDU Complete (length=%d)",state->packet_length); - packetOkOverlay(interface, state->dst, state->packet_length, -1, NULL, 0); + packetOkOverlay(interface, state->dst, state->packet_length, -1, NULL); state->packet_length=sizeof(state->dst)+1; } return 1; diff --git a/serval.h b/serval.h index d97115f2..d213165e 100644 --- a/serval.h +++ b/serval.h @@ -404,7 +404,7 @@ void insertTransactionInCache(unsigned char *transaction_id); int overlay_forward_payload(struct overlay_frame *f); int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, size_t len, - int recvttl, struct sockaddr *recvaddr, socklen_t recvaddrlen); + int recvttl, struct socket_address *recvaddr); int parseMdpPacketHeader(struct decode_context *context, struct overlay_frame *frame, struct overlay_buffer *buffer, struct subscriber **nexthop); int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface *interface, diff --git a/socket.c b/socket.c index 1839980e..e81482d3 100644 --- a/socket.c +++ b/socket.c @@ -44,14 +44,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. int _make_local_sockaddr(struct __sourceloc __whence, struct socket_address *addr, const char *fmt, ...) { bzero(addr, sizeof(*addr)); - addr->addr_un.sun_family = AF_UNIX; + addr->local.sun_family = AF_UNIX; va_list ap; va_start(ap, fmt); - int r = vformf_serval_instance_path(__WHENCE__, addr->addr_un.sun_path, sizeof addr->addr_un.sun_path, fmt, ap); + int r = vformf_serval_instance_path(__WHENCE__, addr->local.sun_path, sizeof addr->local.sun_path, fmt, ap); va_end(ap); if (!r) return WHY("socket name overflow"); - addr->addrlen=sizeof addr->addr_un.sun_family + strlen(addr->addr_un.sun_path) + 1; + addr->addrlen=sizeof addr->local.sun_family + strlen(addr->local.sun_path) + 1; // TODO perform real path transformation in making the serval instance path // if (real_sockaddr(addr, addr) == -1) // return -1; @@ -60,7 +60,7 @@ int _make_local_sockaddr(struct __sourceloc __whence, struct socket_address *add // For the abstract name we use the absolute path name with the initial '/' replaced by the // leading nul. This ensures that different instances of the Serval daemon have different socket // names. - addr->addr_un.sun_path[0] = '\0'; // mark as Linux abstract socket + addr->local.sun_path[0] = '\0'; // mark as Linux abstract socket --addr->addrlen; // do not count trailing nul in abstract socket name #endif // USE_ABSTRACT_NAMESPACE return 0; @@ -80,24 +80,24 @@ int _make_local_sockaddr(struct __sourceloc __whence, struct socket_address *add */ int real_sockaddr(const struct socket_address *src_addr, struct socket_address *dst_addr) { - int src_path_len = src_addr->addrlen - sizeof src_addr->addr_un.sun_family; - if ( src_addr->addrlen >= sizeof src_addr->addr_un.sun_family + 1 - && src_addr->addr_un.sun_family == AF_UNIX - && src_addr->addr_un.sun_path[0] != '\0' - && src_addr->addr_un.sun_path[src_path_len - 1] == '\0' + int src_path_len = src_addr->addrlen - sizeof src_addr->local.sun_family; + if ( src_addr->addrlen >= sizeof src_addr->local.sun_family + 1 + && src_addr->local.sun_family == AF_UNIX + && src_addr->local.sun_path[0] != '\0' + && src_addr->local.sun_path[src_path_len - 1] == '\0' ) { char real_path[PATH_MAX]; size_t real_path_len; - if (realpath(src_addr->addr_un.sun_path, real_path) == NULL) - return WHYF_perror("realpath(%s)", alloca_str_toprint(src_addr->addr_un.sun_path)); - else if ((real_path_len = strlen(real_path) + 1) > sizeof dst_addr->addr_un.sun_path) + if (realpath(src_addr->local.sun_path, real_path) == NULL) + return WHYF_perror("realpath(%s)", alloca_str_toprint(src_addr->local.sun_path)); + else if ((real_path_len = strlen(real_path) + 1) > sizeof dst_addr->local.sun_path) return WHYF("sockaddr overrun: realpath(%s) returned %s", - alloca_str_toprint(src_addr->addr_un.sun_path), alloca_str_toprint(real_path)); + alloca_str_toprint(src_addr->local.sun_path), alloca_str_toprint(real_path)); else if ( real_path_len != src_path_len - || memcmp(real_path, src_addr->addr_un.sun_path, src_path_len) != 0 + || memcmp(real_path, src_addr->local.sun_path, src_path_len) != 0 ) { - memcpy(dst_addr->addr_un.sun_path, real_path, real_path_len); - dst_addr->addrlen = real_path_len + sizeof dst_addr->addr_un.sun_family; + memcpy(dst_addr->local.sun_path, real_path, real_path_len); + dst_addr->addrlen = real_path_len + sizeof dst_addr->local.sun_family; return 1; } } @@ -133,23 +133,23 @@ int cmp_sockaddr(const struct socket_address *addrA, const struct socket_address // Both addresses are in the same family... switch (addrA->addr.sa_family) { case AF_UNIX: { - unsigned pathlenA = addrA->addrlen - sizeof (addrA->addr_un.sun_family); - unsigned pathlenB = addrB->addrlen - sizeof (addrB->addr_un.sun_family); + unsigned pathlenA = addrA->addrlen - sizeof (addrA->local.sun_family); + unsigned pathlenB = addrB->addrlen - sizeof (addrB->local.sun_family); int c; if ( pathlenA > 1 && pathlenB > 1 - && addrA->addr_un.sun_path[0] == '\0' - && addrB->addr_un.sun_path[0] == '\0' + && addrA->local.sun_path[0] == '\0' + && addrB->local.sun_path[0] == '\0' ) { // Both abstract sockets - just compare names, nul bytes are not terminators. - c = memcmp(&addrA->addr_un.sun_path[1], - &addrB->addr_un.sun_path[1], + c = memcmp(&addrA->local.sun_path[1], + &addrB->local.sun_path[1], (pathlenA < pathlenB ? pathlenA : pathlenB) - 1); } else { // Either or both are named local file sockets. If the file names are identical up to the // first nul, then the addresses are equal. This collates abstract socket names, whose first // character is a nul, ahead of all non-empty file socket names. - c = strncmp(addrA->addr_un.sun_path, - addrB->addr_un.sun_path, + c = strncmp(addrA->local.sun_path, + addrB->local.sun_path, (pathlenA < pathlenB ? pathlenA : pathlenB)); } if (c == 0) diff --git a/socket.h b/socket.h index 88a05549..5a167f43 100644 --- a/socket.h +++ b/socket.h @@ -9,7 +9,8 @@ struct socket_address{ socklen_t addrlen; union{ struct sockaddr addr; - struct sockaddr_un addr_un; + struct sockaddr_un local; // name "unix" is a predefined macro + struct sockaddr_in inet; struct sockaddr_storage store; }; }; @@ -53,4 +54,4 @@ ssize_t _recv_message(struct __sourceloc, int fd, struct socket_address *address #define send_message(fd, address, data) _send_message(__WHENCE__, (fd), (address), (data)) #define recv_message(fd, address, data) _recv_message(__WHENCE__, (fd), (address), (data)) -#endif \ No newline at end of file +#endif