Procházet zdrojové kódy

Merge branch 'listen-fixes'

* listen-fixes:
  * Remove some redundant ipv6 error code
  * Only close the listen port if there's one open
  * CTCP bot CHAT will no longer work if the bot does not have an IPV4 IP set.
  * Cleanup DCC/Telnet listening so bot only listens on IPV6 if it was specifically given an IPV6 IP.
  * Fix listen_all() not properly closing the requested dcc
  * Only use port mapping if was asked for a random port
  * Use listen_all() to close the CTCP chat listen port
Bryan Drewery před 16 roky
rodič
revize
7679a6251c
6 změnil soubory, kde provedl 62 přidání a 57 odebrání
  1. 2 0
      doc/UPDATES
  2. 1 1
      src/chanprog.c
  3. 52 45
      src/dccutil.c
  4. 1 1
      src/dccutil.h
  5. 1 1
      src/main.c
  6. 5 9
      src/mod/ctcp.mod/ctcp.c

+ 2 - 0
doc/UPDATES

@@ -73,6 +73,8 @@
   * Bot now attempts to join a channel immediately on invite.
   * Fix bot not setting 'chanmode' channel modes when getting opped.
 * Misc changes
+  * Cleanup DCC/Telnet listening so bot only listens on IPV6 if it was specifically given an IPV6 IP.
+  * CTCP bot CHAT will no longer work if the bot does not have an IPV4 IP set.
   * Add cmd 'release', 'netrelease' and msg-release for releasing a bot's jupenick on a 7 second timer.
   * Add MONITOR support. This speeds up NICK grabbing. (fixes #320)
   * Add set 'deaf' to run bot in DEAF mode on supporting IRCDs. This prevents channel conversations coming to the bot. On by default.

+ 1 - 1
src/chanprog.c

@@ -587,7 +587,7 @@ void rehash_ip() {
 
   if (conf.bot->hub) {
     struct bot_addr *bi = (struct bot_addr *) get_user(&USERENTRY_BOTADDR, conf.bot->u);
-    listen_all(bi->telnet_port, 0);
+    listen_all(bi->telnet_port, 0, 1);
     my_port = bi->telnet_port;
   } else if (conf.bot->localhub) {
     // If not listening on the domain socket, open it up

+ 52 - 45
src/dccutil.c

@@ -831,35 +831,37 @@ do_boot(int idx, const char *by, const char *reason)
 }
 
 int
-listen_all(port_t lport, bool off)
+listen_all(port_t lport, bool off, bool should_v6)
 {
   int idx = -1;
   port_t port, realport;
 
 #ifdef USE_IPV6
-  int i6 = 0;
+  int i6 = -1;
 #endif /* USE_IPV6 */
-  int i = 0, ii = 0;
+  int i = -1;
   struct portmap *pmap = NULL, *pold = NULL;
 
   port = realport = lport;
-  for (pmap = root; pmap; pold = pmap, pmap = pmap->next)
-    if (pmap->realport == port) {
-      port = pmap->mappedto;
-      break;
-    }
+  // If using a random port, lookup the port mapping
+  if (lport == 0) {
+    for (pmap = root; pmap; pold = pmap, pmap = pmap->next)
+      if (pmap->realport == port) {
+        port = pmap->mappedto;
+        break;
+      }
+  }
 
-  for (ii = 0; ii < dcc_total; ii++) {
+  // Look for an existing open port and close if requested
+  for (int ii = 0; ii < dcc_total; ii++) {
     if (dcc[ii].type && (dcc[ii].type == &DCC_TELNET) && (dcc[ii].port == port) &&
-           (!strcmp(dcc[i].nick, "(telnet)") || !strcmp(dcc[i].nick, "(telnet6)"))) {
+           (!strcmp(dcc[ii].nick, "(telnet)") || !strcmp(dcc[ii].nick, "(telnet6)"))) {
       idx = ii;
 
       if (off) {
-        if (pmap) {
-          if (pold)
-            pold->next = pmap->next;
-          else
-            root = pmap->next;
+        if (lport == 0 && pmap) {
+          if (pold) pold->next = pmap->next;
+          else root = pmap->next;
           free(pmap);
         }
 #ifdef USE_IPV6
@@ -883,35 +885,36 @@ listen_all(port_t lport, bool off)
     if (dcc_total >= max_dcc) {
       putlog(LOG_ERRORS, "*", "Can't open listening port - no more DCC Slots");
     } else {
+      if (should_v6 && (conf.bot->net.ip6 || conf.bot->net.host6)) {
 #ifdef USE_IPV6
-      i6 = open_listen_by_af(&port, AF_INET6);
-      if (i6 < 0) {
-        putlog(LOG_ERRORS, "*", "Can't open IPv6 listening port %d - %s", port,
-               i6 == -1 ? "it's taken." : "couldn't assign ip.");
-      } else {
-        /* now setup ipv4/ipv6 listening port */
-        idx = new_dcc(&DCC_TELNET, 0);
-        dcc[idx].addr = 0L;
-        strlcpy(dcc[idx].host6, myipstr(AF_INET6), sizeof(dcc[idx].host6));
-        dcc[idx].port = port;
-        dcc[idx].sock = i6;
-        dcc[idx].timeval = now;
-        strlcpy(dcc[idx].nick, "(telnet6)", NICKLEN);
-        strlcpy(dcc[idx].host, "*", UHOSTLEN);
-        putlog(LOG_DEBUG, "*", "Listening on IPv6 at telnet port %d", port);
+        i6 = open_listen_by_af(&port, AF_INET6);
+        if (i6 < 0) {
+          putlog(LOG_ERRORS, "*", "Can't open IPv6 listening port %d - %s", port, i6 == -1 ? "it's taken." : "couldn't assign ip.");
+        } else {
+          /* now setup ipv4/ipv6 listening port */
+          idx = new_dcc(&DCC_TELNET, 0);
+          dcc[idx].addr = 0L;
+          strlcpy(dcc[idx].host6, myipstr(AF_INET6), sizeof(dcc[idx].host6));
+          dcc[idx].port = port;
+          dcc[idx].sock = i6;
+          dcc[idx].timeval = now;
+          strlcpy(dcc[idx].nick, "(telnet6)", NICKLEN);
+          strlcpy(dcc[idx].host, "*", UHOSTLEN);
+          putlog(LOG_DEBUG, "*", "Listening on IPv6 at telnet port %d", port);
+        }
+#endif
       }
+
+      /* now setup ipv4 listening port */
+#ifdef USE_IPV6
       i = open_listen_by_af(&port, AF_INET);
 #else
       i = open_listen(&port);
 #endif /* USE_IPV6 */
+
       if (i < 0) {
-#ifdef USE_IPV6
-        if (i6 < 0)
-#endif /* USE_IPV6 */
-          putlog(LOG_ERRORS, "*", "Can't open IPv4 listening port %d - %s", port,
-                 i == -1 ? "it's taken." : "couldn't assign ip.");
+        putlog(LOG_ERRORS, "*", "Can't open IPv4 listening port %d - %s", port, i == -1 ? "it's taken." : "couldn't assign ip.");
       } else {
-        /* now setup ipv4 listening port */
         idx = new_dcc(&DCC_TELNET, 0);
         dcc[idx].addr = iptolong(getmyip());
         dcc[idx].port = port;
@@ -921,19 +924,23 @@ listen_all(port_t lport, bool off)
         strlcpy(dcc[idx].host, "*", UHOSTLEN);
         putlog(LOG_DEBUG, "*", "Listening on IPv4 at telnet port %d", port);
       }
+
+      // If was asked for a random listen, save it in a mapping
+      if (lport == 0) {
 #ifdef USE_IPV6
-      if (i > 0 || i6 > 0) {
+        if (i > 0 || (should_v6 && i6 > 0)) {
 #else
-      if (i > 0) {
+          if (i > 0) {
 #endif /* USE_IPV6 */
-        if (!pmap) {
-          pmap = (struct portmap *) my_calloc(1, sizeof(struct portmap));
-          pmap->next = root;
-          root = pmap;
+            if (!pmap) {
+              pmap = (struct portmap *) my_calloc(1, sizeof(struct portmap));
+              pmap->next = root;
+              root = pmap;
+            }
+            pmap->realport = realport;
+            pmap->mappedto = port;
+          }
         }
-        pmap->realport = realport;
-        pmap->mappedto = port;
-      }
     }
   }
   /* if one of the protocols failed, the one which worked will be returned

+ 1 - 1
src/dccutil.h

@@ -57,7 +57,7 @@ void do_boot(int, const char *, const char *);
 int detect_dcc_flood(time_t *, struct chat_info *, int);
 void identd_open(const char * = NULL, const char * = NULL, int identd = 1);
 void identd_close();
-int listen_all(port_t, bool);
+int listen_all(port_t, bool, bool);
 bool valid_idx(int);
 int dcc_read(bd::Stream&);
 void dcc_write(bd::Stream&, int);

+ 1 - 1
src/main.c

@@ -190,7 +190,7 @@ void fatal(const char *s, int recoverable)
 /*  flushlogs(); */
 
   if (my_port)
-    listen_all(my_port, 1); /* close the listening port... */
+    listen_all(my_port, 1, 1); /* close the listening port... */
 
   if (conf.bot && conf.bot->localhub)
     unlink(conf.localhub_socket);

+ 5 - 9
src/mod/ctcp.mod/ctcp.c

@@ -388,14 +388,8 @@ static void ctcp_minutely()
 
   if (listen_time <= 0) {
     for (int i = 0; i < dcc_total; i++) {
-      if (dcc[i].type && (dcc[i].type->flags & DCT_LISTEN) && 
-           (!strcmp(dcc[i].nick, "(telnet)") || !strcmp(dcc[i].nick, "(telnet6)"))) {
-        putlog(LOG_DEBUG, "*", "Closing listening port %d %s", dcc[i].port, dcc[i].nick);
-
-        killsock(dcc[i].sock);
-        lostdcc(i);
-        break;
-      }
+      if (dcc[i].type && (dcc[i].type->flags & DCT_LISTEN) && !strcmp(dcc[i].nick, "(telnet)"))
+        listen_all(0, 1, 0);
     }
   } else
     listen_time--;
@@ -625,7 +619,9 @@ static int ctcp_CHAT(char *nick, char *uhost, struct userrec *u, char *object, c
       if (dcc[i].type && (dcc[i].type->flags & DCT_LISTEN) && (!strcmp(dcc[i].nick, "(telnet)")))
         ix = i;
     }
-    if (dcc_total == max_dcc || (ix < 0 && (ix = listen_all(0, 0)) < 0))
+    if (!iptolong(getmyip())) {
+      simple_snprintf(&ctcp_reply[strlen(ctcp_reply)], sizeof(ctcp_reply) - strlen(ctcp_reply), "\001ERROR no ipv4 ip defined. Use /dcc chat %s\001", botname);
+    } else if (dcc_total == max_dcc || (ix < 0 && (ix = listen_all(0, 0, 0)) < 0))
       strlcat(ctcp_reply, "\001ERROR no telnet port\001", sizeof(ctcp_reply));
     else {
       if (listen_time <= 2)