TODO: nmbd... (doesn't compile yet)
[metze/samba/wip.git] / source3 / nmbd / nmbd_packets.c
index caef1db378569073d1447916f9ad8d7eb7ec6e60..fe21a6b509c0f9b179818c8aca282488c681febf 100644 (file)
@@ -29,8 +29,6 @@ extern int ClientNMB;
 extern int ClientDGRAM;
 extern int global_nmb_port;
 
-extern int num_response_packets;
-
 bool rescan_listen_set = False;
 
 static struct nb_packet_server *packet_server;
@@ -1687,14 +1685,12 @@ struct socket_attributes {
        bool triggered;
 };
 
-static bool create_listen_pollfds(struct pollfd **pfds,
-                                 struct socket_attributes **pattrs,
+static bool create_listen_array(struct socket_attributes **pattrs,
                                  int *pnum_sockets)
 {
        struct subnet_record *subrec = NULL;
        int count = 0;
        int num = 0;
-       struct pollfd *fds;
        struct socket_attributes *attrs;
 
        /* The ClientNMB and ClientDGRAM sockets */
@@ -1718,30 +1714,20 @@ static bool create_listen_pollfds(struct pollfd **pfds,
                }
        }
 
-       fds = talloc_zero_array(NULL, struct pollfd, count);
-       if (fds == NULL) {
-               DEBUG(1, ("create_listen_pollfds: malloc fail for fds. "
-                         "size %d\n", count));
-               return true;
-       }
-
        attrs = talloc_zero_array(NULL, struct socket_attributes, count);
        if (attrs == NULL) {
-               DEBUG(1, ("create_listen_pollfds: malloc fail for attrs. "
+               DEBUG(1, ("talloc fail for attrs. "
                          "size %d\n", count));
-               TALLOC_FREE(fds);
                return true;
        }
 
        num = 0;
 
-       fds[num].fd = ClientNMB;
        attrs[num].fd = ClientNMB;
        attrs[num].type = NMB_PACKET;
        attrs[num].broadcast = false;
        num += 1;
 
-       fds[num].fd = ClientDGRAM;
        attrs[num].fd = ClientDGRAM;
        attrs[num].type = DGRAM_PACKET;
        attrs[num].broadcast = false;
@@ -1750,7 +1736,6 @@ static bool create_listen_pollfds(struct pollfd **pfds,
        for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
 
                if (subrec->nmb_sock != -1) {
-                       fds[num].fd = subrec->nmb_sock;
                        attrs[num].fd = subrec->nmb_sock;
                        attrs[num].type = NMB_PACKET;
                        attrs[num].broadcast = false;
@@ -1758,7 +1743,6 @@ static bool create_listen_pollfds(struct pollfd **pfds,
                }
 
                if (subrec->nmb_bcast != -1) {
-                       fds[num].fd = subrec->nmb_bcast;
                        attrs[num].fd = subrec->nmb_bcast;
                        attrs[num].type = NMB_PACKET;
                        attrs[num].broadcast = true;
@@ -1766,7 +1750,6 @@ static bool create_listen_pollfds(struct pollfd **pfds,
                }
 
                if (subrec->dgram_sock != -1) {
-                       fds[num].fd = subrec->dgram_sock;
                        attrs[num].fd = subrec->dgram_sock;
                        attrs[num].type = DGRAM_PACKET;
                        attrs[num].broadcast = false;
@@ -1774,7 +1757,6 @@ static bool create_listen_pollfds(struct pollfd **pfds,
                }
 
                if (subrec->dgram_bcast != -1) {
-                       fds[num].fd = subrec->dgram_bcast;
                        attrs[num].fd = subrec->dgram_bcast;
                        attrs[num].type = DGRAM_PACKET;
                        attrs[num].broadcast = true;
@@ -1782,9 +1764,6 @@ static bool create_listen_pollfds(struct pollfd **pfds,
                }
        }
 
-       TALLOC_FREE(*pfds);
-       *pfds = fds;
-
        TALLOC_FREE(*pattrs);
        *pattrs = attrs;
 
@@ -1904,57 +1883,45 @@ static void nmbd_fd_handler(struct tevent_context *ev,
 
 bool listen_for_packets(struct messaging_context *msg, bool run_election)
 {
-       static struct pollfd *fds = NULL;
        static struct socket_attributes *attrs = NULL;
        static int listen_number = 0;
        int num_sockets;
        int i;
+       int loop_rtn;
+       int timeout_secs;
 
-       int pollrtn;
-       int timeout;
 #ifndef SYNC_DNS
        int dns_fd;
        int dns_pollidx = -1;
 #endif
        struct processed_packet *processed_packet_list = NULL;
+       struct tevent_timer *te = NULL;
+       bool got_timeout = false;
+       TALLOC_CTX *frame = talloc_stackframe();
 
-       if ((fds == NULL) || rescan_listen_set) {
-               if (create_listen_pollfds(&fds, &attrs, &listen_number)) {
+       if ((attrs == NULL) || rescan_listen_set) {
+               if (create_listen_array(&attrs, &listen_number)) {
                        DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
+                       TALLOC_FREE(frame);
                        return True;
                }
                rescan_listen_set = False;
        }
 
-       /*
-        * "fds" can be enlarged by event_add_to_poll_args
-        * below. Shrink it again to what was given to us by
-        * create_listen_pollfds.
-        */
-
-       fds = talloc_realloc(NULL, fds, struct pollfd, listen_number);
-       if (fds == NULL) {
-               return true;
-       }
        num_sockets = listen_number;
 
 #ifndef SYNC_DNS
        dns_fd = asyncdns_fd();
        if (dns_fd != -1) {
-               fds = talloc_realloc(NULL, fds, struct pollfd, num_sockets+1);
-               if (fds == NULL) {
-                       return true;
-               }
                attrs = talloc_realloc(NULL,
                                        attrs,
                                        struct socket_attributes,
                                        num_sockets + 1);
                if (attrs == NULL) {
-                       TALLOC_FREE(fds);
+                       TALLOC_FREE(frame);
                        return true;
                }
                dns_pollidx = num_sockets;
-               fds[num_sockets].fd = dns_fd;
                attrs[dns_pollidx].fd = dns_fd;
                /*
                 * dummy values, we only need
@@ -1967,12 +1934,17 @@ bool listen_for_packets(struct messaging_context *msg, bool run_election)
 #endif
 
        for (i=0; i<num_sockets; i++) {
-               fds[i].events = POLLIN|POLLHUP;
-       }
-
-       /* Process a signal and timer events now... */
-       if (run_events_poll(nmbd_event_context(), 0, NULL, 0)) {
-               return False;
+               struct tevent_fd *tfd = tevent_add_fd(nmbd_event_context(),
+                                                       frame,
+                                                       attrs[i].fd,
+                                                       TEVENT_FD_READ,
+                                                       nmbd_fd_handler,
+                                                       &attrs[i]);
+               if (tfd == NULL) {
+                       TALLOC_FREE(frame);
+                       return true;
+               }
+               attrs[i].triggered = false;
        }
 
        /*
@@ -1982,26 +1954,40 @@ bool listen_for_packets(struct messaging_context *msg, bool run_election)
         * the time we are expecting the next netbios packet.
         */
 
-       timeout = ((run_election||num_response_packets)
-                  ? 1 : NMBD_SELECT_LOOP) * 1000;
+       if (run_election||num_response_packets) {
+               timeout_secs = 1;
+       } else {
+               timeout_secs = NMBD_SELECT_LOOP;
+       }
 
-       event_add_to_poll_args(nmbd_event_context(), NULL,
-                              &fds, &num_sockets, &timeout);
+       te = tevent_add_timer(nmbd_event_context(),
+                               frame,
+                               tevent_timeval_current_ofs(timeout_secs, 0),
+                               nmbd_timeout_handler,
+                               &got_timeout);
+       if (te == NULL) {
+               TALLOC_FREE(frame);
+               return true;
+       }
 
-       pollrtn = poll(fds, num_sockets, timeout);
+       loop_rtn = tevent_loop_once(nmbd_event_context());
 
-       if (run_events_poll(nmbd_event_context(), pollrtn, fds, num_sockets)) {
-               return False;
+       if (loop_rtn == -1) {
+               TALLOC_FREE(frame);
+               return true;
        }
 
-       if (pollrtn == -1) {
-               return False;
+       if (got_timeout) {
+               TALLOC_FREE(frame);
+               return false;
        }
 
 #ifndef SYNC_DNS
        if ((dns_fd != -1) && (dns_pollidx != -1) &&
-           (fds[dns_pollidx].revents & (POLLIN|POLLHUP|POLLERR))) {
+           attrs[dns_pollidx].triggered){
                run_dns_queue(msg);
+               TALLOC_FREE(frame);
+               return false;
        }
 #endif
 
@@ -2012,7 +1998,7 @@ bool listen_for_packets(struct messaging_context *msg, bool run_election)
                int client_fd;
                int client_port;
 
-               if ((fds[i].revents & (POLLIN|POLLHUP|POLLERR)) == 0) {
+               if (!attrs[i].triggered) {
                        continue;
                }
 
@@ -2089,6 +2075,7 @@ bool listen_for_packets(struct messaging_context *msg, bool run_election)
        }
 
        free_processed_packet_list(&processed_packet_list);
+       TALLOC_FREE(frame);
        return False;
 }