Просмотр исходного кода

* Re-implemented DNSWAIT dcc table

svn: 1488
Bryan Drewery 21 лет назад
Родитель
Сommit
6139935b48
6 измененных файлов с 110 добавлено и 39 удалено
  1. 49 2
      src/adns.c
  2. 1 1
      src/adns.h
  3. 33 16
      src/botnet.c
  4. 11 11
      src/dcc.c
  5. 10 2
      src/dcc.h
  6. 6 7
      src/mod/server.mod/servmsg.c

+ 49 - 2
src/adns.c

@@ -102,7 +102,7 @@ time_t async_resolve_timeout = 30;
 static void 
 dns_display(int idx, char *buf)
 {
-  sprintf(buf, "adns   waited %lis", now - dcc[idx].timeval);
+  sprintf(buf, "named   waited %lis", now - dcc[idx].timeval);
 }
 
 static void
@@ -142,9 +142,52 @@ static struct dcc_table dns_handler = {
   dns_display,
   NULL,
   NULL,
+  NULL
+};
+
+static void dcc_dnswait(int idx, char *buf, int len)
+{
+  /* Ignore anything now. */
+}
+
+static void eof_dcc_dnswait(int idx)
+{
+  putlog(LOG_MISC, "*", "Lost connection while resolving hostname [%s/%d]",
+         iptostr(htonl(dcc[idx].addr)), dcc[idx].port);
+  killsock(dcc[idx].sock);
+  lostdcc(idx);
+}
+
+static void display_dcc_dnswait(int idx, char *buf)
+{
+  sprintf(buf, "dns   waited %lis", now - dcc[idx].timeval);
+}
+
+static void kill_dcc_dnswait(int idx, void *x)
+{
+  struct dns_info *p = (struct dns_info *) x;
+
+  if (p) {
+    if (p->cbuf)
+      free(p->cbuf);
+  }
+}
+
+struct dcc_table DCC_DNSWAIT = {
+ "DNSWAIT",
+  DCT_VALIDIDX,
+  eof_dcc_dnswait,
+  dcc_dnswait,
+  NULL,
   NULL,
+  display_dcc_dnswait,
+  kill_dcc_dnswait,
+  NULL,
+  NULL
 };
 
+
+
 /*
 static void async_timeout(void *client_data)
 {
@@ -903,7 +946,11 @@ int egg_dns_init()
 
 bool valid_dns_id(int idx, int id)
 {
-  if (valid_idx(idx) && (id == -1 || dcc[idx].dns_id == id))
+
+sdprintf("valid_dns_id, idx: %d id: %d / dcc[idx].id... %d", idx, id, dcc[idx].u.dns->dns_id);
+  if (id == -1)
+    return 1;
+  if (valid_idx(idx) && dcc[idx].u.dns && dcc[idx].u.dns->dns_id && dcc[idx].u.dns->dns_id == id)
     return 1;
   sdprintf("dns_id: %d is not associated with dead idx: %d", id, idx);
   return 0;

+ 1 - 1
src/adns.h

@@ -7,7 +7,7 @@
 
 #define DNS_PORT 53
 
-typedef void (*dns_callback_t)(int id, void *client_data, const char *query, char **result);
+typedef void (*dns_callback_t)(int, void *client_data, const char *query, char **result);
 
 int egg_dns_init(void);
 //int egg_dns_shutdown(void);

+ 33 - 16
src/botnet.c

@@ -892,7 +892,7 @@ int botunlink(int idx, char *nick, char *reason)
   return 0;
 }
 
-static void botlink_dns_callback(int id, void *, const char *, char **);
+static void botlink_dns_callback(int, void *, const char *, char **);
 
 /* Link to another bot
  */
@@ -940,17 +940,17 @@ int botlink(char *linker, int idx, char *nick)
 	putlog(LOG_BOTS, "*", "%s %s at %s:%d ...", BOT_LINKING, nick,
 	       bi->address, bi->telnet_port);
 
-      i = new_dcc(&DCC_FORK_BOT, sizeof(struct bot_info));
+      i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
+
       dcc[i].timeval = now;
       dcc[i].port = bi->telnet_port;
       dcc[i].user = u;
       strcpy(dcc[i].nick, nick);
       strcpy(dcc[i].host, bi->address);
+      dcc[i].u.dns->cptr = strdup(linker);
+      dcc[i].u.dns->ibuf = idx;
 
-      strcpy(dcc[i].u.bot->linker, linker);
-      dcc[i].u.bot->numver = idx;
-
-      dcc[i].dns_id = egg_dns_lookup(bi->address, 20, botlink_dns_callback, (void *) i);
+      dcc[i].u.dns->dns_id = egg_dns_lookup(bi->address, 20, botlink_dns_callback, (void *) i);
      
       return 1;
       /* wait for async reply */
@@ -966,6 +966,14 @@ static void botlink_dns_callback(int id, void *client_data, const char *host, ch
   if (!valid_dns_id(i, id))
     return;
 
+  int idx = -1;
+  char *linker = NULL;
+
+  if (valid_idx(i)) {
+    idx = dcc[i].u.dns->ibuf;
+    linker = strdup(dcc[i].u.dns->cptr);
+  }
+
   if (!ips) {
     lostdcc(i);
     return;
@@ -973,9 +981,14 @@ static void botlink_dns_callback(int id, void *client_data, const char *host, ch
 
   dcc[i].addr = inet_addr(ips[0]);
 
+  changeover_dcc(i, &DCC_FORK_BOT, sizeof(struct bot_info));
   dcc[i].timeval = now;
   strcpy(dcc[i].u.bot->version, "(primitive bot)");
   strcpy(dcc[i].u.bot->sysname, "*");
+  strcpy(dcc[i].u.bot->linker, linker);
+  dcc[i].u.bot->numver = idx;
+  free(linker);
+
   dcc[i].u.bot->port = dcc[i].port;             /* Remember where i started */
 #ifdef USE_IPV6
   dcc[i].sock = getsock(SOCK_STRONGCONN, is_dotted_ip(ips[0]));
@@ -1081,7 +1094,7 @@ void tandem_relay(int idx, char *nick, register int i)
     return;
   }
 
-  i = new_dcc(&DCC_FORK_RELAY, sizeof(struct relay_info));
+  i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
 
   if (i < 0) {
     dprintf(idx, "%s\n", DCC_TOOMANYDCCS1);
@@ -1106,12 +1119,9 @@ void tandem_relay(int idx, char *nick, register int i)
   dcc[idx].u.relay->chat = ci;
   dcc[idx].u.relay->old_status = dcc[idx].status;
 
-
   dcc[i].timeval = now;
-  dcc[i].u.relay->sock = dcc[idx].sock;
-  dcc[i].u.relay->idx = idx;
-
-  dcc[i].dns_id = egg_dns_lookup(bi->address, 20, tandem_relay_dns_callback, (void *) i);
+  dcc[i].u.dns->ibuf = idx;
+  dcc[i].u.dns->dns_id = egg_dns_lookup(bi->address, 20, tandem_relay_dns_callback, (void *) i);
 
   return;
   /* wait for async reply */
@@ -1124,8 +1134,8 @@ static void tandem_relay_dns_callback(int id, void *client_data, const char *hos
   if (!valid_dns_id(i, id))
     return;
 
-  if (dcc[i].type)
-    idx = dcc[i].u.relay->idx;
+  if (valid_idx(i))
+    idx = dcc[i].u.dns->ibuf;
   
   if (idx < 0) {
     putlog(LOG_MISC, "*", "%s  %d -> %d", BOT_CANTFINDRELAYUSER, i, idx);
@@ -1159,9 +1169,14 @@ static void tandem_relay_dns_callback(int id, void *client_data, const char *hos
 
   dcc[idx].u.relay->sock = dcc[i].sock;
 
+  int sock = dcc[idx].u.dns->ibuf;
+
+  changeover_dcc(i, &DCC_FORK_RELAY, sizeof(struct relay_info));
+
   dcc[i].addr = inet_addr(ips[0]);
 
   dcc[i].u.relay->chat = (struct chat_info *) calloc(1, sizeof(struct chat_info));
+  dcc[i].u.relay->sock = sock;
   dcc[i].u.relay->port = dcc[i].port;
   dcc[i].u.relay->chat->away = NULL;
   dcc[i].u.relay->chat->msgs_per_sec = 0;
@@ -1189,8 +1204,9 @@ static void pre_relay(int idx, char *buf, register int len)
     }
   }
   if (tidx < 0) {
+    /* Now try to find it among the DNSWAIT sockets instead. */
     for (i = 0; i < dcc_total; i++) {
-      if (dcc[i].type && !dcc[i].addr && (dcc[i].sock == dcc[idx].u.relay->sock)) {
+      if (dcc[i].type && (dcc[i].type != &DCC_DNSWAIT || (dcc[i].sock == dcc[idx].u.relay->sock))) {
 	tidx = i;
 	break;
       }
@@ -1235,8 +1251,9 @@ static void failed_pre_relay(int idx)
     }
   }
   if (tidx < 0) {
+    /* Now try to find it among the DNSWAIT sockets instead. */
     for (i = 0; i < dcc_total; i++) {
-      if (dcc[i].type && !dcc[i].addr && (dcc[i].sock == dcc[idx].u.relay->sock)) {
+      if (dcc[i].type && (dcc[i].type != &DCC_DNSWAIT || (dcc[i].sock == dcc[idx].u.relay->sock))) {
 	tidx = i;
 	break;
       }

+ 11 - 11
src/dcc.c

@@ -1193,7 +1193,7 @@ detect_telnet_flood(char *floodhost)
   return 0;
 }
 
-static void dcc_telnet_dns_callback(int id, void *, const char *, char **);
+static void dcc_telnet_dns_callback(int, void *, const char *, char **);
 
 static void
 dcc_telnet(int idx, char *buf, int ii)
@@ -1246,10 +1246,10 @@ dcc_telnet(int idx, char *buf, int ii)
     return;
   }
 
-  i = new_dcc(&DCC_IDENTWAIT, 0);
+  i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
 
-  dcc[i].sock = sock;
   dcc[i].addr = ip;
+  dcc[i].sock = sock;
   strcpy(dcc[i].host, s);
 #ifdef USE_IPV6
   if (sockprotocol(sock) == AF_INET6)
@@ -1258,24 +1258,23 @@ dcc_telnet(int idx, char *buf, int ii)
   dcc[i].port = port;
   dcc[i].timeval = now;
   strcpy(dcc[i].nick, "*");
-  dcc[i].u.other = (void *) idx;
-  dcc[i].dns_id = egg_dns_reverse(s, 20, dcc_telnet_dns_callback, (void *) i);
+
+  dcc[i].u.dns->ibuf = idx;
+  dcc[i].u.dns->dns_id = egg_dns_reverse(s, 20, dcc_telnet_dns_callback, (void *) i);
 }
 
 static void dcc_telnet_dns_callback(int id, void *client_data, const char *ip, char **hosts)
 {
-  int idx = -1, i = (int) client_data;
+  int i = (int) client_data;
 
   if (!valid_dns_id(i, id))
     return;
 
-  int j = 0, sock;
+  int j = 0, sock, idx = -1;
   char s2[UHOSTLEN + 20] = "";
 
-  if (dcc[i].type)
-    idx = (int) dcc[i].u.other;
-
-  dcc[i].u.other = 0;
+  if (valid_idx(i))
+    idx = dcc[i].u.dns->ibuf;
 
   strncpyz(dcc[i].host, hosts ? hosts[0] : ip, UHOSTLEN);
 
@@ -1304,6 +1303,7 @@ static void dcc_telnet_dns_callback(int id, void *client_data, const char *ip, c
   }
 /* .  ssl_link(dcc[i].sock, ACCEPT_SSL); */
 
+  changeover_dcc(i, &DCC_IDENTWAIT, 0);
   dcc[i].timeval = now;
   dcc[i].u.ident_sock = dcc[idx].sock;
   

+ 10 - 2
src/dcc.h

@@ -28,6 +28,7 @@ struct dcc_t {
   struct userrec *user;
   union {
     struct chat_info *chat;
+    struct dns_info *dns;
     struct file_info *file;
     struct edit_info *edit;
     struct xfer_info *xfer;
@@ -51,7 +52,6 @@ struct dcc_t {
   int simul;                    /* this will hold the idx on the remote bot to return result. */
   int msgc;			/* forward the output back to irc? */
   int whowas;
-  int dns_id;
   port_t port;
   char simulbot[NICKLEN];       /* used for hub->leaf cmd simulation, holds bot that results should be sent to */
   char hash[MD5_HASH_LENGTH + 1];                /* used for dcc authing */
@@ -63,6 +63,14 @@ struct dcc_t {
 #endif /* USE_IPV6 */
 };
 
+struct dns_info {
+  char *cbuf;			/* free`d when done */
+  char *cptr;
+  int dns_id;
+  int ibuf;
+  int ibuf2;
+//  struct dcc_table *type;       /* type we are doing the lookup for          */
+};
 
 struct chat_info {
   struct msgq *buffer;          /* a buffer of outgoing lines
@@ -219,7 +227,7 @@ extern char			network[];
 extern struct dcc_table DCC_CHAT, DCC_BOT, DCC_BOT_NEW,
  DCC_RELAY, DCC_RELAYING, DCC_FORK_RELAY, DCC_PRE_RELAY, DCC_CHAT_PASS,
  DCC_FORK_BOT, DCC_SOCKET, DCC_TELNET_ID, DCC_TELNET_NEW, DCC_TELNET_PW,
- DCC_TELNET, DCC_IDENT, DCC_IDENTWAIT, DCC_IDENTD, DCC_IDENTD_CONNECT;
+ DCC_TELNET, DCC_IDENT, DCC_IDENTWAIT, DCC_IDENTD, DCC_IDENTD_CONNECT, DCC_DNSWAIT;
 
 #ifdef HUB
 void send_timesync(int);

+ 6 - 7
src/mod/server.mod/servmsg.c

@@ -1352,7 +1352,7 @@ static void connect_server(void)
  
     trying_server = now;
 
-    newidx = new_dcc(&SERVER_SOCKET, strlen(pass) + 1);
+    newidx = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
     if (newidx < 0) {
       putlog(LOG_SERV, "*", "NO MORE DCC CONNECTIONS -- Can't create server connection.");
       trying_server = 0;
@@ -1374,14 +1374,14 @@ static void connect_server(void)
 
     dcc[newidx].timeval = now;
     dcc[newidx].sock = -1;
-    dcc[newidx].u.other = (void *) strdup(pass);
+    dcc[newidx].u.dns->cbuf = strdup(pass);
 
     cycle_time = 15;		/* wait 15 seconds before attempting next server connect */
 
     /* I'm resolving... don't start another server connect request */
     resolvserv = 1;
     /* Resolve the hostname. */
-    dcc[newidx].dns_id = egg_dns_lookup(botserver, 20, server_dns_callback, (void *) newidx);
+    dcc[newidx].u.dns->dns_id = egg_dns_lookup(botserver, 20, server_dns_callback, (void *) newidx);
     /* wait for async reply */
   }
 }
@@ -1409,10 +1409,9 @@ static void server_dns_callback(int id, void *client_data, const char *host, cha
   if (addr.family == AF_INET)
     dcc[idx].addr = htonl(addr.u.addr.s_addr);
 
-  strcpy(serverpass, (char *) dcc[idx].u.other);
-//  changeover_dcc(idx, &SERVER_SOCKET, 0);
-  free(dcc[idx].u.other);
-  dcc[idx].u.other = NULL;
+  strcpy(serverpass, (char *) dcc[idx].u.dns->cbuf);
+  free(dcc[idx].u.dns->cbuf);
+  changeover_dcc(idx, &SERVER_SOCKET, 0);
 
   identd_open();