smbd-server: Handle ip drop event and close listening socket
authorVinit Agnihotri <vagnihotri@ddn.com>
Wed, 28 Feb 2024 11:56:23 +0000 (03:56 -0800)
committerMartin Schwenke <martins@samba.org>
Tue, 16 Apr 2024 23:51:45 +0000 (23:51 +0000)
Signed-off-by: Vinit Agnihotri <vagnihotri@ddn.com>
Reviewed-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/smbd/server.c

index ed0f7746966a542009e0d79042371501992b6e53..aba980e9375d100b29ca4fa28e27e32a52b21ef1 100644 (file)
@@ -1639,6 +1639,33 @@ static void smbd_init_addrchange(TALLOC_CTX *mem_ctx,
        tevent_req_set_callback(req, smbd_addr_changed, state);
 }
 
+static void smbd_close_socket_for_ip(struct smbd_parent_context *parent,
+                                    struct sockaddr_storage *addr)
+{
+       struct smbd_open_socket *s = NULL;
+
+       for (s = parent->sockets; s != NULL; s = s->next) {
+               struct sockaddr_storage a;
+               socklen_t addr_len = sizeof(a);
+
+               if (getsockname(s->fd, (struct sockaddr *)&a, &addr_len) < 0) {
+                       DBG_NOTICE("smbd: Unable to get address - skip\n");
+                       continue;
+               }
+               if (sockaddr_equal((struct sockaddr *)&a,
+                                  (struct sockaddr *)addr)) {
+                       char addrstr[INET6_ADDRSTRLEN];
+
+                       DLIST_REMOVE(parent->sockets, s);
+                       TALLOC_FREE(s);
+                       print_sockaddr(addrstr, sizeof(addrstr), addr);
+                       DBG_NOTICE("smbd: Closed listening socket for %s\n",
+                                  addrstr);
+                       return;
+               }
+       }
+}
+
 static void smbd_addr_changed(struct tevent_req *req)
 {
        struct smbd_addrchanged_state *state = tevent_req_callback_data(
@@ -1666,6 +1693,8 @@ static void smbd_addr_changed(struct tevent_req *req)
                           "on if_index %u\n",
                           addrstr, if_index);
 
+               smbd_close_socket_for_ip(state->parent, &addr);
+
                goto rearm;
        }