Răsfoiți Sursa

Merge branch 'cache-005'

* cache-005:
  * Fix cached_005 not being initialized
  * Only replay cache if it exists
  * Send VERSION if the 005 was not cached for some reason
  * Update doc to reflect that segfault has been fixed from missing 005 on restart (fixes #378)
  * Write cache out to socksfile and finish replaying
  * Fix cache on got005 to use 005
  * Replay server cache on restart
  * Cache with a nick of '.' since it is ignored and to prevent double msgs
  * Don't cache double msgs
  * Cache 005 into DP_CACHE
  * Add DP_CACHE for caching server information for use after restart

Conflicts:

	doc/UPDATES
Bryan Drewery 17 ani în urmă
părinte
comite
e9cb226081
7 a modificat fișierele cu 58 adăugiri și 4 ștergeri
  1. 1 0
      doc/UPDATES
  2. 2 1
      src/dccutil.c
  3. 1 0
      src/dccutil.h
  4. 11 2
      src/misc.c
  5. 36 1
      src/mod/server.mod/server.c
  6. 1 0
      src/mod/server.mod/server.h
  7. 6 0
      src/mod/server.mod/servmsg.c

+ 1 - 0
doc/UPDATES

@@ -31,6 +31,7 @@
 * Fix 'cmd_rehash' problems on hubs.
 * Fix 'HQ' user getting wiped in -t mode resulting in a crash. (fixes #298)
 * Fix bots linking to the wrong hub not giving a good reason why they failed in the log. (fixes #369)
+* Fix segfault on some ircds after restart due to them not giving 005 information on VERSION. (fixes #378)
 
 1.2.15.1
 * Fix leaf bots not updating behind other hubs (fixes #419)

+ 2 - 1
src/dccutil.c

@@ -301,11 +301,12 @@ dprintf(int idx, const char *format, ...)
       case DP_SERVER_NEXT:
       case DP_HELP_NEXT:
       case DP_DUMP:
+      case DP_CACHE:
         if (conf.bot->hub)
           break;
         len -= remove_crlf_r(buf);
 
-        if ((idx == DP_DUMP || floodless)) {
+        if ((idx == DP_DUMP || (floodless && idx != DP_CACHE))) {
          if (serv != -1) {
            if (debug_output)
              putlog(LOG_SRVOUT, "@", "[d->] %s", buf);

+ 1 - 0
src/dccutil.h

@@ -27,6 +27,7 @@ struct portmap {
 #define DP_SERVER_NEXT  0x7FF8
 #define DP_HELP_NEXT    0x7FF9
 #define DP_DUMP		0x8000
+#define DP_CACHE	0x8001
 
 
 

+ 11 - 2
src/misc.c

@@ -615,7 +615,7 @@ readsocks(const char *fname)
   char buf[1024] = "", *nick = NULL, *jnick = NULL, *bufp = NULL, *type = NULL, *buf_ptr = NULL, *ip4 = NULL, *ip6 = NULL;
   time_t old_buildts = 0;
 
-  bool enc = 0, first = 1;
+  bool enc = 0, first = 1, cached_005 = 0;
   const char salt1[] = SALT1;
 
   while (fgets(buf, sizeof(buf), f) != NULL) {
@@ -650,6 +650,11 @@ readsocks(const char *fname)
       ip4 = strdup(bufp);
     else if (!strcmp(type, STR("+ip6")))
       ip6 = strdup(bufp);
+    else if (!strcmp(type, STR("+serv_cache"))) {
+      if (!cached_005 && strstr(bufp, "005"))
+        cached_005 = 1;
+      dprintf(DP_CACHE, bufp);
+    }
 
     if (enc)
       free(buf_ptr);
@@ -679,7 +684,10 @@ readsocks(const char *fname)
       add_server(nserv);
       curserv = 0;
       rehash_server(dcc[servidx].host, nick);
-      dprintf(DP_DUMP, "VERSION\n");
+      if (cached_005)
+        replay_cache(servidx, NULL);
+      else
+        dprintf(DP_DUMP, "VERSION\n");
       reset_chans = 1;
     }
   }
@@ -744,6 +752,7 @@ restart(int idx)
   lfprintf(socks->f, STR("+buildts %li\n"), buildts);
   lfprintf(socks->f, STR("+ip4 %s\n"), myipstr(AF_INET));
   lfprintf(socks->f, STR("+ip6 %s\n"), myipstr(AF_INET6));
+  replay_cache(-1, socks->f);
 
   fflush(socks->f);
   socks->my_close();

+ 36 - 1
src/mod/server.mod/server.c

@@ -105,6 +105,7 @@ static bool fast_deq(int);
 static char *splitnicks(char **);
 static void msgq_clear(struct msgq_head *qh);
 static int stack_limit = 4;
+static bool replaying_cache = 0;
 
 /* New bind tables. */
 static bind_table_t *BT_raw = NULL, *BT_msg = NULL;
@@ -122,7 +123,7 @@ bind_table_t *BT_ctcr = NULL, *BT_ctcp = NULL, *BT_msgc = NULL;
 
 /* Maximum messages to store in each queue. */
 static int maxqmsg = 300;
-static struct msgq_head mq, hq, modeq;
+static struct msgq_head mq, hq, modeq, cacheq;
 static int burst;
 
 #include "cmdsserv.c"
@@ -371,6 +372,28 @@ char *splitnicks(char **rest)
   return r;
 }
 
+void replay_cache(int idx, FILE *f) {
+  if (!cacheq.head) return;
+
+  struct msgq *r = NULL;
+  char *p_ptr = NULL, *p = NULL;
+
+  replaying_cache = 1;
+
+  for (r = cacheq.head; r; r = r->next) {
+    if (f)
+      lfprintf(f, STR("+serv_cache %s\n"), r->msg);
+    else {
+      //Create temporary buffer since server_activity may squash the buffer
+      p_ptr = p = strdup(r->msg);
+      server_activity(idx, p, r->len);
+      free(p_ptr);
+    }
+  }
+
+  replaying_cache = 0;
+}
+
 static bool fast_deq(int which)
 {
   if (!use_fastdeq)
@@ -497,6 +520,7 @@ static void empty_msgq()
   msgq_clear(&modeq);
   msgq_clear(&mq);
   msgq_clear(&hq);
+  msgq_clear(&cacheq);
   burst = 0;
 }
 
@@ -544,6 +568,12 @@ void queue_server(int which, char *buf, int len)
       doublemsg = 1;
     break;
 
+  case DP_CACHE:
+    h = &cacheq;
+    tempq = cacheq;
+    doublemsg = 0;
+    break;
+
   default:
     putlog(LOG_MISC, "*", "!!! queuing unknown type to server!!");
     return;
@@ -632,6 +662,11 @@ void queue_server(int which, char *buf, int len)
     case DP_HELP_NEXT:
       putlog(LOG_SRVOUT, "@", "[!!h] %s", buf);
       break;
+#ifdef DEBUG
+    case DP_CACHE:
+      sdprintf("CACHE: %s", buf);
+      break;
+#endif
     }
   }
 

+ 1 - 0
src/mod/server.mod/server.h

@@ -72,6 +72,7 @@ void clearq(struct server_list *);
 void nuke_server(const char *);
 bool match_my_nick(char *);
 void rehash_server(const char *, const char *);
+void replay_cache(int, FILE *);
 void join_chans();
 void check_hostmask();
 void next_server(int *, char *, port_t *, char *);

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

@@ -242,6 +242,12 @@ got005(char *from, char *msg)
 
   newsplit(&msg); /* nick */
 
+  //Cache the results for later parsing if needed (after a restart)
+  //Sending 'VERSION' does not work on all servers, plus this speeds
+  //up a restart by removing the need to wait for the information
+  if (!replaying_cache)
+    dprintf(DP_CACHE, ":%s 005 . %s", from, msg);
+
   while ((tmp = newsplit(&msg))[0]) {
     p = NULL;