diff -urN clussed-19981231/CHANGELOG clussed-19990103/CHANGELOG --- clussed-19981231/CHANGELOG Thu Dec 31 13:05:56 1998 +++ clussed-19990103/CHANGELOG Sun Jan 3 15:15:48 1999 @@ -103,3 +103,13 @@ me that the given password should be checked against something 8-) -hessu) +Sun Jan 3 15:06:25 EET 1999 + + Small fix in f_luser.c and f_nuser.c for list commands efficiency + (stupid me - no need to realloc for every call). + Check for (s == s->next) in select_loop, there's a bug somewhere + and we're looping. + Fixed a bug in pc_19, it stuck looping with a bad callsign or a + duplicate node. + Made loop detection report the reason for the holding. + diff -urN clussed-19981231/STRUCTURE clussed-19990103/STRUCTURE --- clussed-19981231/STRUCTURE Fri Dec 25 21:37:10 1998 +++ clussed-19990103/STRUCTURE Sat Jan 2 17:39:16 1999 @@ -5,61 +5,78 @@ Incoming connection: - 1. csock.c: Noticed by select_loop lq (listen queue) check + 1. csock.c: Noticed by select_loop() lq (listen queue) check which calls method lq->accept - 2. af_xxxx.c: xxxx_accept prepares the socket, calls sock_login - 3. csock.c: sock_login calls auth_login for authenticated listeners - (INET for the moment), luser_login for others + 2. af_xxxx.c: xxxx_accept() prepares the socket, calls sock_login() + 3. csock.c: sock_login() calls auth_login() for authenticated listeners + (INET for the moment), luser_login() for others (auth_login calls luser_login) - 4. luser.c: luser_login either prepares the local user (and calls - lnuser_login), or calls link_login if the user appears to + 4. luser.c: luser_login() either prepares the local user (and calls + lnuser_login()), or calls link_login() if the user appears to be an incoming linker Incoming disconnection: - 1: csock.c: Noticed by sock_read (returns EOF), select_loop calls - sock_close - 2: sock_close calls s->disc_handler + 1: csock.c: Noticed by sock_read() (returns EOF), select_loop() calls + sock_close() + 2: sock_close() calls s->disc_handler 3: disc_handler clears data structures for the user, link, whatever - 4: sock_close clears data structures for the socket + 4: sock_close() clears data structures for the socket Incoming data: - 1: csock.c: Noticed by select_loop, calls sock_read to read data to + 1: csock.c: Noticed by select_loop(), calls sock_read() to read data to buffer and do optional decompression - 2: csock.c: select_loop calls sock_handle, which does optional + 2: csock.c: select_loop() calls sock_handle(), which does optional telnet negotiation, optional EOL searching for eol_text - sockets and calls s->in_handle method (which points to - luser_handler, pc_handler, etc) + sockets and calls s->in_handler method (which points to + luser_handler(), pc_handler(), etc) Outgoing data: - 1: whatever calls csprintf, csputc, csputs, or something - 2: csock.c: csprintf calls csputs calls csputc - 3: cputc does optional EOL conversion, calls cswritec - 4: cswritec does optional telnet negotiation, calls csrwritec - 5: csrwritec stuffs the data to buffer, and if buffer is full, - csrwritec does optional compression and calls csrflush + 1: whatever calls csprintf(), csputc(), csputs(), or something + 2: csock.c: csprintf() calls csputs() calls csputc() + 3: cputc() does optional EOL conversion, calls cswritec() + 4: cswritec() does optional telnet negotiation, calls csrwritec() + 5: csrwritec() stuffs the data to buffer, and if buffer is full, + does optional compression and calls csrflush() to send the data. 6: Else, the data is flushed when someone calls csflush(), which - does the optional compression and calls csrflush. - csflush() is called by csflush_all once every second - (off the timer). + does the optional compression and calls csrflush(). + csflush() is called by csflush_all() once every second + (off the timer). Not advisable to call csflush() yourself, + for bandwidth efficiency reasons. Never ever call csr* + yourself. + +User command handling: + 1: csock.c: sock_handle() calls s->in_handler, which points to + luser_handler() + 2: luser.c: luser_handler() calls command(cluster_cmds), cluster_cmds + list is defined in cluster.c + 3: command.c: finds the relevant command from the cluster_cmds list, + executes it and returns what the command handler returned + 4: the command handler implements the command. IF the command + (or an input handler in general) calls sock_disconnect(), it + must return what sock_disconnect returned, and NOT refer to + the socket structure after calling sock_disconnect, since + it might be freed alredy. When successful, a handler returns 0. + PC link message reception: - 1: net_pc.c: pc_handler calls parse_pc to do the ^ argument parsing + 1: net_pc.c: pc_handler() calls parse_pc() to do the ^ argument parsing and finds the correct handler method from the pcmds table, - calls the pc_NN handler - 2: net_pc.c: pc_NN handler parses the message, for messages + calls the pc_NN() handler + 2: net_pc.c: pc_NN() handler parses the message, for messages containing data allocates data structure and stuffs the - fields to the structure, calls the relevant net_XXX handler - 3: network.c: net_XXX inserts data to local memory structures + fields to the structure, calls the relevant net_XXX() handler + 3: network.c: net_XXX() inserts data to local memory structures (and files), calls user_XXX to send the data to local users, - calls link_XXX to send the data to links - 4: cluster.c: user_XXX sends data to local users which are interested + calls link_XXX() to send the data to links + 4: cluster.c: user_XXX() sends data to local users which are interested in the data - 5: net_link.c: link_XXX calls pc_XXX to send the data to PC links - (will later call cll_XXX to send clulink messages too) - 6: net_pc.c: pc_XXX sends data to links using pc_send or pc_sendall + 5: net_link.c: link_XXX() calls pc_XXX() to send the data to PC links + (will later call cll_XXX() to send clulink messages too) + 6: net_pc.c: pc_XXX() sends data to links using pc_send() or + pc_sendall() diff -urN clussed-19981231/csock.c clussed-19990103/csock.c --- clussed-19981231/csock.c Wed Dec 30 21:46:15 1998 +++ clussed-19990103/csock.c Sun Jan 3 15:06:11 1999 @@ -1006,6 +1006,10 @@ for (s = sockets; (s); s = nexts) { nexts = s->next; + if (s == nexts) { + log(L_CRIT, "OUCH. select_loop(): s->next == s (%s:%s/%s) - deadlock !!!", s->call, s->node, s->port); + exit(1); + } if (FD_ISSET(s->fd, &readchk)) { if ((r = sock_read(s)) < 0) { sock_close(s); diff -urN clussed-19981231/csock.h clussed-19990103/csock.h --- clussed-19981231/csock.h Wed Dec 30 03:38:54 1998 +++ clussed-19990103/csock.h Sun Jan 3 14:59:09 1999 @@ -8,8 +8,12 @@ #undef HAVE_ROSE #include +#ifdef HAVE_AX25 #include +#endif +#ifdef HAVE_ROSE #include +#endif #include #include "luser.h" @@ -157,9 +161,16 @@ char *port; /* Port call, only set across the port list */ union { +#ifdef HAVE_AX25 struct full_sockaddr_ax25 ax25; +#endif +#ifdef HAVE_ROSE + struct sockaddr_rose rose; +#endif +#ifdef HAVE_INET struct sockaddr_in inet; +#endif } sockaddr; int addrlen; diff -urN clussed-19981231/f_luser.c clussed-19990103/f_luser.c --- clussed-19981231/f_luser.c Tue Dec 29 04:02:35 1998 +++ clussed-19990103/f_luser.c Thu Dec 31 13:35:11 1998 @@ -96,7 +96,7 @@ char st[80]; datum key; char **l; - int llen = 20; + int llen = 40; int lent = 0; int n, i = 0; @@ -108,9 +108,10 @@ key = db_firstkey(luser_db); while (key.dptr) { key.dptr[key.dsize - 1] = '\0'; /* just to be sure. */ - if (i == llen) - llen += 20; - l = hrealloc(l, llen * sizeof(char *)); + if (i == llen) { + llen += (llen / 2); + l = hrealloc(l, llen * sizeof(char *)); + } l[i] = key.dptr; lent++; i++; diff -urN clussed-19981231/f_nuser.c clussed-19990103/f_nuser.c --- clussed-19981231/f_nuser.c Tue Dec 29 04:02:39 1998 +++ clussed-19990103/f_nuser.c Thu Dec 31 13:35:29 1998 @@ -179,7 +179,7 @@ char st[80]; datum key; char **l; - int llen = 20; + int llen = 200; int lent = 0; int n, i = 0; @@ -191,9 +191,10 @@ key = db_firstkey(nuser_db); while (key.dptr) { key.dptr[key.dsize - 1] = '\0'; /* just to be sure. */ - if (i == llen) - llen += 20; - l = hrealloc(l, llen * sizeof(char *)); + if (i == llen) { + llen += (llen / 2); + l = hrealloc(l, llen * sizeof(char *)); + } l[i] = key.dptr; lent++; i++; diff -urN clussed-19981231/net_pc.c clussed-19990103/net_pc.c --- clussed-19981231/net_pc.c Thu Dec 31 13:12:00 1998 +++ clussed-19990103/net_pc.c Sun Jan 3 15:23:08 1999 @@ -584,7 +584,8 @@ if (!(n = get_node((call_t *)argv[1]))) return 0; if (n->via != l) - return caught_loop(l); + return caught_loop(l, "PC16: Duplicate user %s, already seen via %s", + argv[1], (n->via) ? n->via->name : "localnode"); hops = pchops2int(argv[argc-1]); for (i = 2; i < argc-1; i++) { @@ -666,14 +667,15 @@ if (i > argc - 5) break; if (!valid_call((call_t *)argv[i+1])) - continue; + goto skip; if ((n = get_node((call_t *)argv[i+1]))) if (n->via != l) { - caught_loop(l); + caught_loop(l, "PC19: Duplicate node %s, already seen via %s", + n->call, (n->via) ? n->via->name : "localnode"); free_nodel(nl); return -2; } else - continue; + goto skip; n = hmalloc(sizeof(struct node_t)); *prevp = n; n->prevp = prevp; @@ -693,6 +695,7 @@ n->rtt_ok = 0; n->pinging = 0; n->locked = 0; +skip: i += 4; } @@ -773,6 +776,7 @@ int pc_38(struct link_t *l, int argc, char **argv) { char *p, *p2; + struct node_t *n; if (argc != 2) return invalid_argc(l, 2, argc, argv); @@ -785,8 +789,9 @@ p2++; } - if (get_node((call_t *)p)) - return caught_loop(l); + if ((n = get_node((call_t *)p))) + return caught_loop(l, "PC38: Duplicate node %s, already seen via %s", + p, (n->via) ? n->via->name : "localnode"); p = p2; } diff -urN clussed-19981231/network.c clussed-19990103/network.c --- clussed-19981231/network.c Wed Dec 30 11:25:49 1998 +++ clussed-19990103/network.c Sun Jan 3 15:14:25 1999 @@ -9,6 +9,7 @@ #include #include #include +#include #include "hmalloc.h" #include "ctypes.h" @@ -388,12 +389,20 @@ * Drop this link immediately, due to a caught loop */ -int caught_loop(struct link_t *l) +int caught_loop(struct link_t *l, char *reason, ...) { + va_list args; + char s[LOG_LEN]; + + va_start(args, reason); + vsnprintf(s, LOG_LEN, reason, args); + va_end(args); + if (l->state == ls_held) return -2; /* might be several reasons to hold a link in a single received message */ - log(L_ERR, "Link: %s: Loop detected - link held!", l->name); + log(L_ERR, "Link: %s: Loop detected (%s) - link held!", + l->name, s); l->state = ls_held; l->dreason = dr_loop; diff -urN clussed-19981231/network.h clussed-19990103/network.h --- clussed-19981231/network.h Wed Dec 30 04:03:51 1998 +++ clussed-19990103/network.h Sun Jan 3 15:08:55 1999 @@ -219,7 +219,7 @@ extern int link_login(struct csock_t *sock, struct link_t *l); extern void link_logout(struct csock_t *sock); -extern int caught_loop(struct link_t *l); +extern int caught_loop(struct link_t *l, char *reason, ...); /* Cluster events */ extern int net_dx(struct dx_t *dx); /* DX */