diff options
author | Stefan Metzmacher <metze@sernet.de> | 2008-01-16 13:57:50 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2009-01-19 07:05:44 +0100 |
commit | a5b3975cf71f0bf114832c958ba855646c69832c (patch) | |
tree | 75718b70f2818ed7cdc49a5b26812b74ca6d574e /source4/nbt_server | |
parent | ebab6d6ce40ec4d64126964c0223aa2bdef99094 (diff) | |
download | samba-a5b3975cf71f0bf114832c958ba855646c69832c.tar.gz samba-a5b3975cf71f0bf114832c958ba855646c69832c.tar.xz samba-a5b3975cf71f0bf114832c958ba855646c69832c.zip |
nbt_server: redirect incoming response packets to the correct interface
We may send requests packets (WACK challenges or similar things)
via a different udp socket than the socket we receive the
matching response. We need to setup an unexpected handler
on the nbt sockets and redirect responses to the correct
nbt_socket. (By redirect I mean we use the correct
nbt_socket structure, we're *not* resending the packet
with sendto() via the kernel...)
metze
(from samba4wins tree 7ce8e705e5a9aabb787d17fbec7a078d9d6780dc)
Diffstat (limited to 'source4/nbt_server')
-rw-r--r-- | source4/nbt_server/interfaces.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/source4/nbt_server/interfaces.c b/source4/nbt_server/interfaces.c index f5ac49255a..4bc18feb59 100644 --- a/source4/nbt_server/interfaces.c +++ b/source4/nbt_server/interfaces.c @@ -75,6 +75,58 @@ static void nbtd_request_handler(struct nbt_name_socket *nbtsock, } } +static void nbtd_unexpected_handler(struct nbt_name_socket *nbtsock, + struct nbt_name_packet *packet, + struct socket_address *src) +{ + struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data, + struct nbtd_interface); + struct nbtd_server *nbtsrv = iface->nbtsrv; + struct nbtd_interface *i; + struct nbt_name_request *req = NULL; + + nbtsrv->stats.total_received++; + + DEBUG(10,("unexpected from src[%s] on interface[%p] %s/%s\n", + src->addr, iface, iface->ip_address, iface->netmask)); + + /* try the broadcast interface */ + if (nbtsrv->bcast_interface) { + i = nbtsrv->bcast_interface; + req = idr_find(i->nbtsock->idr, packet->name_trn_id); + } + + /* try the wins server client interface */ + if (!req && nbtsrv->wins_interface) { + i = nbtsrv->wins_interface; + req = idr_find(i->nbtsock->idr, packet->name_trn_id); + } + + /* try all other interfaces... */ + if (!req) { + for (i = nbtsrv->interfaces; i; i = i->next) { + if (i == iface) { + continue; + } + req = idr_find(i->nbtsock->idr, packet->name_trn_id); + if (req) break; + } + } + + if (!req) { + DEBUG(10,("unexpected from src[%s] unable to redirected\n", src->addr)); + return; + } + + DEBUG(10,("unexpected from src[%s] redirected to interface[%p] %s/%s\n", + src->addr, i, i->ip_address, i->netmask)); + + /* + * redirect the incoming response to the socket + * we sent the matching request + */ + nbt_name_socket_handle_response_packet(req, packet, src); +} /* find a registered name on an interface @@ -180,6 +232,7 @@ static NTSTATUS nbtd_add_socket(struct nbtd_server *nbtsrv, talloc_free(unicast_address); nbt_set_incoming_handler(iface->nbtsock, nbtd_request_handler, iface); + nbt_set_unexpected_handler(iface->nbtsock, nbtd_unexpected_handler, iface); /* also setup the datagram listeners */ status = nbtd_dgram_setup(iface, bind_address); |