summaryrefslogtreecommitdiffstats
path: root/src/peer.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-04-20 18:43:12 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-04-20 18:43:12 +0200
commit3fcb880682a02e1952eb710a5952a0d7f92f41e1 (patch)
treeab829de58a61a2e6b422979df2f352caf196f6bb /src/peer.c
parentdaf3d6e8db9ef39b50dce040f864fb409bd7044a (diff)
downloadfastd-3fcb880682a02e1952eb710a5952a0d7f92f41e1.tar
fastd-3fcb880682a02e1952eb710a5952a0d7f92f41e1.zip
Greatly improve handling of hosts with multiple IP addresses
Diffstat (limited to 'src/peer.c')
-rw-r--r--src/peer.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/peer.c b/src/peer.c
index f4d62e3..14af83c 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -36,14 +36,14 @@ static inline void on_establish(fastd_context_t *ctx, const fastd_peer_t *peer)
if (!ctx->conf->on_establish)
return;
- fastd_shell_exec(ctx, ctx->conf->on_establish, ctx->conf->on_establish_dir, peer, peer->sock->bound_addr, &peer->address, NULL);
+ fastd_shell_exec(ctx, ctx->conf->on_establish, ctx->conf->on_establish_dir, peer, &peer->local_address, &peer->address, NULL);
}
static inline void on_disestablish(fastd_context_t *ctx, const fastd_peer_t *peer) {
if (!ctx->conf->on_disestablish)
return;
- fastd_shell_exec(ctx, ctx->conf->on_disestablish, ctx->conf->on_disestablish_dir, peer, peer->sock->bound_addr, &peer->address, NULL);
+ fastd_shell_exec(ctx, ctx->conf->on_disestablish, ctx->conf->on_disestablish_dir, peer, &peer->local_address, &peer->address, NULL);
}
static inline void free_socket(fastd_context_t *ctx, fastd_peer_t *peer) {
@@ -133,6 +133,8 @@ static void reset_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
free_socket(ctx, peer);
+ memset(&peer->local_address, 0, sizeof(peer->local_address)),
+
ctx->conf->protocol->reset_peer_state(ctx, peer);
int i, deleted = 0;
@@ -275,6 +277,10 @@ bool fastd_peer_address_equal(const fastd_peer_address_t *addr1, const fastd_pee
return false;
if (addr1->in6.sin6_port != addr2->in6.sin6_port)
return false;
+ if (IN6_IS_ADDR_LINKLOCAL(&addr1->in6.sin6_addr)) {
+ if (addr1->in6.sin6_scope_id != addr2->in6.sin6_scope_id)
+ return false;
+ }
}
return true;
@@ -299,15 +305,15 @@ static inline void reset_peer_address(fastd_context_t *ctx, fastd_peer_t *peer)
memset(&peer->address, 0, sizeof(fastd_peer_address_t));
}
-bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *new_peer, fastd_socket_t *sock, const fastd_peer_address_t *addr) {
- if (addr->sa.sa_family == AF_UNSPEC) {
+bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *new_peer, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr) {
+ if (remote_addr->sa.sa_family == AF_UNSPEC) {
if (fastd_peer_is_established(new_peer))
fastd_peer_reset(ctx, new_peer);
}
else {
fastd_peer_t *peer;
for (peer = ctx->peers; peer; peer = peer->next) {
- if (!fastd_peer_address_equal(&peer->address, addr))
+ if (!fastd_peer_address_equal(&peer->address, remote_addr))
continue;
if (peer == new_peer)
@@ -323,12 +329,15 @@ bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *new_peer, fast
}
}
- new_peer->address = *addr;
+ new_peer->address = *remote_addr;
if (sock && sock->addr && sock != new_peer->sock) {
free_socket(ctx, new_peer);
new_peer->sock = sock;
}
+ if (local_addr)
+ new_peer->local_address = *local_addr;
+
return true;
}