|
@@ -831,35 +831,37 @@ do_boot(int idx, const char *by, const char *reason)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int
|
|
int
|
|
|
-listen_all(port_t lport, bool off)
|
|
|
|
|
|
|
+listen_all(port_t lport, bool off, bool should_v6)
|
|
|
{
|
|
{
|
|
|
int idx = -1;
|
|
int idx = -1;
|
|
|
port_t port, realport;
|
|
port_t port, realport;
|
|
|
|
|
|
|
|
#ifdef USE_IPV6
|
|
#ifdef USE_IPV6
|
|
|
- int i6 = 0;
|
|
|
|
|
|
|
+ int i6 = -1;
|
|
|
#endif /* USE_IPV6 */
|
|
#endif /* USE_IPV6 */
|
|
|
- int i = 0, ii = 0;
|
|
|
|
|
|
|
+ int i = -1;
|
|
|
struct portmap *pmap = NULL, *pold = NULL;
|
|
struct portmap *pmap = NULL, *pold = NULL;
|
|
|
|
|
|
|
|
port = realport = lport;
|
|
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) &&
|
|
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;
|
|
idx = ii;
|
|
|
|
|
|
|
|
if (off) {
|
|
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);
|
|
free(pmap);
|
|
|
}
|
|
}
|
|
|
#ifdef USE_IPV6
|
|
#ifdef USE_IPV6
|
|
@@ -883,35 +885,36 @@ listen_all(port_t lport, bool off)
|
|
|
if (dcc_total >= max_dcc) {
|
|
if (dcc_total >= max_dcc) {
|
|
|
putlog(LOG_ERRORS, "*", "Can't open listening port - no more DCC Slots");
|
|
putlog(LOG_ERRORS, "*", "Can't open listening port - no more DCC Slots");
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ if (should_v6 && (conf.bot->net.ip6 || conf.bot->net.host6)) {
|
|
|
#ifdef USE_IPV6
|
|
#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);
|
|
i = open_listen_by_af(&port, AF_INET);
|
|
|
#else
|
|
#else
|
|
|
i = open_listen(&port);
|
|
i = open_listen(&port);
|
|
|
#endif /* USE_IPV6 */
|
|
#endif /* USE_IPV6 */
|
|
|
|
|
+
|
|
|
if (i < 0) {
|
|
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 {
|
|
} else {
|
|
|
- /* now setup ipv4 listening port */
|
|
|
|
|
idx = new_dcc(&DCC_TELNET, 0);
|
|
idx = new_dcc(&DCC_TELNET, 0);
|
|
|
dcc[idx].addr = iptolong(getmyip());
|
|
dcc[idx].addr = iptolong(getmyip());
|
|
|
dcc[idx].port = port;
|
|
dcc[idx].port = port;
|
|
@@ -921,19 +924,23 @@ listen_all(port_t lport, bool off)
|
|
|
strlcpy(dcc[idx].host, "*", UHOSTLEN);
|
|
strlcpy(dcc[idx].host, "*", UHOSTLEN);
|
|
|
putlog(LOG_DEBUG, "*", "Listening on IPv4 at telnet port %d", port);
|
|
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
|
|
#ifdef USE_IPV6
|
|
|
- if (i > 0 || i6 > 0) {
|
|
|
|
|
|
|
+ if (i > 0 || (should_v6 && i6 > 0)) {
|
|
|
#else
|
|
#else
|
|
|
- if (i > 0) {
|
|
|
|
|
|
|
+ if (i > 0) {
|
|
|
#endif /* USE_IPV6 */
|
|
#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
|
|
/* if one of the protocols failed, the one which worked will be returned
|