mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Improve struct socket_address
Add struct sockaddr_in 'inet' union field, rename 'addr_un' union field to 'local' Replace recvwithttl()'s (struct sockaddr *) and socklen_t pair of args with single (struct socket_address *) arg
This commit is contained in:
parent
d45470ce81
commit
dafa1fc186
14
mdp_client.c
14
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
|
||||
)
|
||||
|
10
net.c
10
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;
|
||||
}
|
||||
|
4
net.h
4
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
|
||||
|
@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include <fnmatch.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
2
serval.h
2
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,
|
||||
|
48
socket.c
48
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)
|
||||
|
5
socket.h
5
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
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user