Use binded port in local_addr
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
66
mud.c
66
mud.c
@@ -151,6 +151,7 @@ struct mud {
|
|||||||
uint64_t send_timeout;
|
uint64_t send_timeout;
|
||||||
uint64_t time_tolerance;
|
uint64_t time_tolerance;
|
||||||
uint64_t keyx_timeout;
|
uint64_t keyx_timeout;
|
||||||
|
struct sockaddr_storage addr;
|
||||||
struct mud_path *paths;
|
struct mud_path *paths;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
struct {
|
struct {
|
||||||
@@ -443,6 +444,30 @@ mud_get_paths(struct mud *mud, unsigned *ret_count)
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mud_copy_port(struct sockaddr_storage *d, struct sockaddr_storage *s)
|
||||||
|
{
|
||||||
|
uint16_t port = 0;
|
||||||
|
|
||||||
|
switch (s->ss_family) {
|
||||||
|
case AF_INET:
|
||||||
|
port = ((struct sockaddr_in *)s)->sin_port;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
port = ((struct sockaddr_in6 *)s)->sin6_port;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (d->ss_family) {
|
||||||
|
case AF_INET:
|
||||||
|
((struct sockaddr_in *)d)->sin_port = port;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
((struct sockaddr_in6 *)d)->sin6_port = port;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct mud_path *
|
static struct mud_path *
|
||||||
mud_get_path(struct mud *mud, struct sockaddr_storage *local_addr,
|
mud_get_path(struct mud *mud, struct sockaddr_storage *local_addr,
|
||||||
struct sockaddr_storage *addr, int create)
|
struct sockaddr_storage *addr, int create)
|
||||||
@@ -452,6 +477,8 @@ mud_get_path(struct mud *mud, struct sockaddr_storage *local_addr,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mud_copy_port(local_addr, &mud->addr);
|
||||||
|
|
||||||
for (unsigned i = 0; i < mud->count; i++) {
|
for (unsigned i = 0; i < mud->count; i++) {
|
||||||
struct mud_path *path = &mud->paths[i];
|
struct mud_path *path = &mud->paths[i];
|
||||||
|
|
||||||
@@ -477,7 +504,7 @@ mud_get_path(struct mud *mud, struct sockaddr_storage *local_addr,
|
|||||||
|
|
||||||
if (!path) {
|
if (!path) {
|
||||||
struct mud_path *paths = realloc(mud->paths,
|
struct mud_path *paths = realloc(mud->paths,
|
||||||
(mud->count + 1) * sizeof(struct mud_path));
|
(mud->count + 1) * sizeof(struct mud_path));
|
||||||
|
|
||||||
if (!paths)
|
if (!paths)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -650,7 +677,7 @@ mud_set_keyx_timeout(struct mud *mud, unsigned long msec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mud_set_state(struct mud *mud, struct sockaddr *peer, enum mud_state state)
|
mud_set_state(struct mud *mud, struct sockaddr *addr, enum mud_state state)
|
||||||
{
|
{
|
||||||
if (!mud->peer.set ||
|
if (!mud->peer.set ||
|
||||||
(state < MUD_DOWN) || (state > MUD_UP)) {
|
(state < MUD_DOWN) || (state > MUD_UP)) {
|
||||||
@@ -658,12 +685,13 @@ mud_set_state(struct mud *mud, struct sockaddr *peer, enum mud_state state)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage local_addr;
|
||||||
|
|
||||||
if (mud_ss_from_sa(&addr, peer))
|
if (mud_ss_from_sa(&local_addr, addr))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
struct mud_path *path = mud_get_path(mud, &addr, &mud->peer.addr, state > MUD_DOWN);
|
struct mud_path *path = mud_get_path(mud,
|
||||||
|
&local_addr, &mud->peer.addr, state > MUD_DOWN);
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -862,6 +890,8 @@ mud_create(struct sockaddr *addr)
|
|||||||
mud->tc = MUD_PACKET_TC;
|
mud->tc = MUD_PACKET_TC;
|
||||||
mud->mtu = sizeof(struct mud_packet);
|
mud->mtu = sizeof(struct mud_packet);
|
||||||
|
|
||||||
|
memcpy(&mud->addr, addr, addrlen);
|
||||||
|
|
||||||
mud_keyx_init(mud);
|
mud_keyx_init(mud);
|
||||||
randombytes_buf(mud->local.kiss, sizeof(mud->local.kiss));
|
randombytes_buf(mud->local.kiss, sizeof(mud->local.kiss));
|
||||||
|
|
||||||
@@ -966,21 +996,16 @@ mud_decrypt(struct mud *mud,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mud_localaddr(struct sockaddr_storage *addr, struct msghdr *msg, int family)
|
mud_localaddr(struct sockaddr_storage *addr, struct msghdr *msg)
|
||||||
{
|
{
|
||||||
int cmsg_level = IPPROTO_IP;
|
|
||||||
int cmsg_type = MUD_PKTINFO;
|
|
||||||
|
|
||||||
if (family == AF_INET6) {
|
|
||||||
cmsg_level = IPPROTO_IPV6;
|
|
||||||
cmsg_type = IPV6_PKTINFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
|
struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
|
||||||
|
|
||||||
for (; cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
|
for (; cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
|
||||||
if ((cmsg->cmsg_level == cmsg_level) &&
|
if ((cmsg->cmsg_level == IPPROTO_IP) &&
|
||||||
(cmsg->cmsg_type == cmsg_type))
|
(cmsg->cmsg_type == MUD_PKTINFO))
|
||||||
|
break;
|
||||||
|
if ((cmsg->cmsg_level == IPPROTO_IPV6) &&
|
||||||
|
(cmsg->cmsg_type == IPV6_PKTINFO))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,18 +1013,21 @@ mud_localaddr(struct sockaddr_storage *addr, struct msghdr *msg, int family)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
memset(addr, 0, sizeof(struct sockaddr_storage));
|
memset(addr, 0, sizeof(struct sockaddr_storage));
|
||||||
addr->ss_family = family;
|
|
||||||
|
|
||||||
if (family == AF_INET) {
|
if (cmsg->cmsg_level == IPPROTO_IP) {
|
||||||
|
addr->ss_family = AF_INET;
|
||||||
memcpy(&((struct sockaddr_in *)addr)->sin_addr,
|
memcpy(&((struct sockaddr_in *)addr)->sin_addr,
|
||||||
MUD_PKTINFO_SRC(CMSG_DATA(cmsg)),
|
MUD_PKTINFO_SRC(CMSG_DATA(cmsg)),
|
||||||
sizeof(struct in_addr));
|
sizeof(struct in_addr));
|
||||||
} else {
|
} else {
|
||||||
|
addr->ss_family = AF_INET6;
|
||||||
memcpy(&((struct sockaddr_in6 *)addr)->sin6_addr,
|
memcpy(&((struct sockaddr_in6 *)addr)->sin6_addr,
|
||||||
&((struct in6_pktinfo *)CMSG_DATA(cmsg))->ipi6_addr,
|
&((struct in6_pktinfo *)CMSG_DATA(cmsg))->ipi6_addr,
|
||||||
sizeof(struct in6_addr));
|
sizeof(struct in6_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mud_unmapv4(addr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1237,7 +1265,7 @@ mud_recv(struct mud *mud, void *data, size_t size)
|
|||||||
|
|
||||||
struct sockaddr_storage local_addr;
|
struct sockaddr_storage local_addr;
|
||||||
|
|
||||||
if (mud_localaddr(&local_addr, &msg, addr.ss_family))
|
if (mud_localaddr(&local_addr, &msg))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
struct mud_path *path = mud_get_path(mud, &local_addr, &addr, 1);
|
struct mud_path *path = mud_get_path(mud, &local_addr, &addr, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user