Setup cmsg directly in mud_send_path()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
142
mud.c
142
mud.c
@@ -86,10 +86,6 @@ struct mud_path {
|
|||||||
unsigned backup : 1;
|
unsigned backup : 1;
|
||||||
} state;
|
} state;
|
||||||
struct sockaddr_storage local_addr, addr;
|
struct sockaddr_storage local_addr, addr;
|
||||||
struct {
|
|
||||||
unsigned char data[256];
|
|
||||||
size_t size;
|
|
||||||
} ctrl;
|
|
||||||
struct {
|
struct {
|
||||||
uint64_t send_time;
|
uint64_t send_time;
|
||||||
int remote;
|
int remote;
|
||||||
@@ -99,7 +95,6 @@ struct mud_path {
|
|||||||
} mtu;
|
} mtu;
|
||||||
unsigned char kiss[MUD_SID_SIZE];
|
unsigned char kiss[MUD_SID_SIZE];
|
||||||
} conf;
|
} conf;
|
||||||
unsigned char *tc;
|
|
||||||
uint64_t rdt;
|
uint64_t rdt;
|
||||||
uint64_t rtt;
|
uint64_t rtt;
|
||||||
uint64_t sdt;
|
uint64_t sdt;
|
||||||
@@ -299,9 +294,7 @@ mud_send_path(struct mud *mud, struct mud_path *path, uint64_t now,
|
|||||||
if (!size)
|
if (!size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const socklen_t addrlen = path->addr.ss_family == AF_INET
|
unsigned char ctrl[256];
|
||||||
? sizeof(struct sockaddr_in)
|
|
||||||
: sizeof(struct sockaddr_in6);
|
|
||||||
|
|
||||||
struct iovec iov = {
|
struct iovec iov = {
|
||||||
.iov_base = data,
|
.iov_base = data,
|
||||||
@@ -310,15 +303,55 @@ mud_send_path(struct mud *mud, struct mud_path *path, uint64_t now,
|
|||||||
|
|
||||||
struct msghdr msg = {
|
struct msghdr msg = {
|
||||||
.msg_name = &path->addr,
|
.msg_name = &path->addr,
|
||||||
.msg_namelen = addrlen,
|
|
||||||
.msg_iov = &iov,
|
.msg_iov = &iov,
|
||||||
.msg_iovlen = 1,
|
.msg_iovlen = 1,
|
||||||
.msg_control = path->ctrl.data,
|
.msg_control = ctrl,
|
||||||
.msg_controllen = path->ctrl.size,
|
.msg_controllen = sizeof(ctrl),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (path->tc)
|
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
memcpy(path->tc, &tc, sizeof(tc));
|
|
||||||
|
if (path->addr.ss_family == AF_INET) {
|
||||||
|
cmsg->cmsg_level = IPPROTO_IP;
|
||||||
|
cmsg->cmsg_type = MUD_PKTINFO;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN(MUD_PKTINFO_SIZE);
|
||||||
|
|
||||||
|
memcpy(MUD_PKTINFO_DST(CMSG_DATA(cmsg)),
|
||||||
|
&((struct sockaddr_in *)&path->local_addr)->sin_addr,
|
||||||
|
sizeof(struct in_addr));
|
||||||
|
|
||||||
|
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
||||||
|
cmsg->cmsg_level = IPPROTO_IP;
|
||||||
|
cmsg->cmsg_type = IP_TOS;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||||
|
|
||||||
|
memcpy(CMSG_DATA(cmsg), &tc, sizeof(int));
|
||||||
|
|
||||||
|
msg.msg_namelen = sizeof(struct sockaddr_in);
|
||||||
|
msg.msg_controllen = CMSG_SPACE(MUD_PKTINFO_SIZE)
|
||||||
|
+ CMSG_SPACE(sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path->addr.ss_family == AF_INET6) {
|
||||||
|
cmsg->cmsg_level = IPPROTO_IPV6;
|
||||||
|
cmsg->cmsg_type = IPV6_PKTINFO;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||||
|
|
||||||
|
memcpy(&((struct in6_pktinfo *)CMSG_DATA(cmsg))->ipi6_addr,
|
||||||
|
&((struct sockaddr_in6 *)&path->local_addr)->sin6_addr,
|
||||||
|
sizeof(struct in6_addr));
|
||||||
|
|
||||||
|
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
||||||
|
cmsg->cmsg_level = IPPROTO_IPV6;
|
||||||
|
cmsg->cmsg_type = IPV6_TCLASS;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||||
|
|
||||||
|
memcpy(CMSG_DATA(cmsg), &tc, sizeof(int));
|
||||||
|
|
||||||
|
msg.msg_namelen = sizeof(struct sockaddr_in6);
|
||||||
|
msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo))
|
||||||
|
+ CMSG_SPACE(sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t ret = sendmsg(mud->fd, &msg, flags);
|
ssize_t ret = sendmsg(mud->fd, &msg, flags);
|
||||||
path->send_time = now;
|
path->send_time = now;
|
||||||
@@ -362,82 +395,6 @@ mud_cmp_addr(struct sockaddr_storage *a, struct sockaddr_storage *b)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
mud_set_path(struct mud_path *path, struct sockaddr_storage *local_addr,
|
|
||||||
struct sockaddr_storage *addr)
|
|
||||||
{
|
|
||||||
struct msghdr msg = {
|
|
||||||
.msg_control = path->ctrl.data,
|
|
||||||
.msg_controllen = sizeof(path->ctrl.data),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
|
||||||
|
|
||||||
if (!cmsg)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
memset(&path->ctrl, 0, sizeof(path->ctrl));
|
|
||||||
|
|
||||||
if (local_addr)
|
|
||||||
memmove(&path->local_addr, local_addr, sizeof(*local_addr));
|
|
||||||
|
|
||||||
memmove(&path->addr, addr, sizeof(*addr));
|
|
||||||
|
|
||||||
if (addr->ss_family == AF_INET) {
|
|
||||||
if (local_addr) {
|
|
||||||
cmsg->cmsg_level = IPPROTO_IP;
|
|
||||||
cmsg->cmsg_type = MUD_PKTINFO;
|
|
||||||
cmsg->cmsg_len = CMSG_LEN(MUD_PKTINFO_SIZE);
|
|
||||||
|
|
||||||
memcpy(MUD_PKTINFO_DST(CMSG_DATA(cmsg)),
|
|
||||||
&((struct sockaddr_in *)local_addr)->sin_addr,
|
|
||||||
sizeof(struct in_addr));
|
|
||||||
|
|
||||||
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
|
||||||
|
|
||||||
if (!cmsg)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
path->ctrl.size += CMSG_SPACE(MUD_PKTINFO_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmsg->cmsg_level = IPPROTO_IP;
|
|
||||||
cmsg->cmsg_type = IP_TOS;
|
|
||||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
|
||||||
|
|
||||||
path->tc = CMSG_DATA(cmsg);
|
|
||||||
path->ctrl.size += CMSG_SPACE(sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr->ss_family == AF_INET6) {
|
|
||||||
if (local_addr) {
|
|
||||||
cmsg->cmsg_level = IPPROTO_IPV6;
|
|
||||||
cmsg->cmsg_type = IPV6_PKTINFO;
|
|
||||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
|
||||||
|
|
||||||
memcpy(&((struct in6_pktinfo *)CMSG_DATA(cmsg))->ipi6_addr,
|
|
||||||
&((struct sockaddr_in6 *)local_addr)->sin6_addr,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
|
|
||||||
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
|
||||||
|
|
||||||
if (!cmsg)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
path->ctrl.size += CMSG_SPACE(sizeof(struct in6_pktinfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
cmsg->cmsg_level = IPPROTO_IPV6;
|
|
||||||
cmsg->cmsg_type = IPV6_TCLASS;
|
|
||||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
|
||||||
|
|
||||||
path->tc = CMSG_DATA(cmsg);
|
|
||||||
path->ctrl.size += CMSG_SPACE(sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mud_path *
|
static struct mud_path *
|
||||||
mud_path(struct mud *mud, struct sockaddr_storage *local_addr,
|
mud_path(struct mud *mud, struct sockaddr_storage *local_addr,
|
||||||
struct sockaddr_storage *addr, int create)
|
struct sockaddr_storage *addr, int create)
|
||||||
@@ -467,11 +424,8 @@ mud_path(struct mud *mud, struct sockaddr_storage *local_addr,
|
|||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (mud_set_path(path, local_addr, addr)) {
|
memmove(&path->local_addr, local_addr, sizeof(*local_addr));
|
||||||
free(path);
|
memmove(&path->addr, addr, sizeof(*addr));
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
path->conf.mtu.local = mud->mtu; // XXX
|
path->conf.mtu.local = mud->mtu; // XXX
|
||||||
path->next = mud->path;
|
path->next = mud->path;
|
||||||
|
|||||||
Reference in New Issue
Block a user