Fix more IAuth bugs and add IAUTH log target.
authorMichael Poole <mdpoole@troilus.org>
Sun, 1 May 2005 16:11:01 +0000 (16:11 +0000)
committerMichael Poole <mdpoole@troilus.org>
Sun, 1 May 2005 16:11:01 +0000 (16:11 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1392 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
doc/readme.log
include/ircd_log.h
ircd/engine_epoll.c
ircd/ircd_auth.c
ircd/ircd_log.c
ircd/s_misc.c

index de627dcb5f19816d3efc284ab12e024ff9715e12..106d3c51c8bfe0ed554453d6a3a488301a060adf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2005-05-01  Michael Poole <mdpoole@troilus.org>
+
+       * doc/readme.log: Document IAUTH log target, remove docs for
+       OLDLOG log target.
+
+       * include/ircd_log.h: Add LS_IAUTH target, remove LS_OLDLOG.
+
+       * ircd/ircd_log.c (logDesc): Likewise.
+
+       * ircd/engine_epoll.c (engine_loop): Handle EPOLLHUP for all
+       sockets (e.g. when connecting) and do not generate read/write
+       events in the same pass as error or EOF events.
+
+       * ircd/ircd_auth.c: Convert old sendto and debug messages to use
+       the LS_IAUTH log target.  Consistently use IAUTH_CONNECTED flag
+       instead of comparing fd to -1.
+       (iauth_reconnect): If already connected, disconnect and schedule a
+       reconnect later, since an immediate reconnect can cause assertion
+       failure in the event engine.  Also schedule a reconnect when the
+       connection attempt fails.
+       (iauth_read): Reconnect on IO_FAILURE.
+       (iauth_sock_callback): Disconnect and schedule a reconnect on both
+       error (after reporting the error) and EOF.
+       (iauth_start_client): Record the IAuth request in the client.
+       (iauth_exit_client): Report the client exit.
+
+       * ircd/s_misc.c (exit_one_client): Fix formatting.
+
 2005-04-30  Michael Poole <mdpoole@troilus.org>
 
        * ircd/ircd_auth.c (iauth_connect): Initialize (but do not add)
index d4bfe70326837922f358b777c971bcce09ccb4ba..c5dda8977584a109fecd2a6701cb98b519c442c7 100644 (file)
@@ -107,15 +107,15 @@ higher will be logged.
  * SOCKET - Used to report problems with sockets.  By default, log
    messages to this subsystem go nowhere.
 
+ * IAUTH - Used to report connects, disconnects and errors for the
+   IAuth authorization mechanism.  By default, log messages to this
+   subsystem go to the "NETWORK" server notice mask.
+
  * DEBUG - Used only when debugging is enabled.  All log messages to
    this subsystem go either to the console or to the debug log file
    compiled into the server, as well as to the "DEBUG" server notice
    mask.  This is the only subsystem with a default log file.
 
- * OLDLOG - Not used anywhere.  This is a left-over from when the
-   logging subsystem was first created.  Log messages to this
-   subsystem go nowhere.
-
 Configuration
 
 The true power of the logging subsystem comes from its extremely
index 956908cb6af8b2eb44e736a0f29a3c9633d39144..48d63a87ed3572f5f9d737a066767629e9c22c7c 100644 (file)
@@ -63,8 +63,8 @@ enum LogSys {
   LS_OPER,       /**< Users becoming operators. */
   LS_RESOLVER,   /**< DNS resolver errors. */
   LS_SOCKET,     /**< Unexpected socket operation errors. */
+  LS_IAUTH,      /**< IAuth status. */
   LS_DEBUG,      /**< Debug messages. */
-  LS_OLDLOG,     /**< Old logging messages (no longer used). */
   LS_LAST_SYSTEM /**< Count of valid LogSys values. */
 };
 
index 004c7f03c4796150892a1b79648b5ad74543a278..3fdfecf893e120b06a66408d92add8e595a363cb 100644 (file)
@@ -276,9 +276,9 @@ engine_loop(struct Generators *gen)
           gen_ref_dec(sock);
           continue;
         }
-      }
-
-      switch (s_state(sock)) {
+      } else if (events[i].events & EPOLLHUP) {
+        event_generate(ET_EOF, sock, 0);
+      } else switch (s_state(sock)) {
       case SS_CONNECTING:
         if (events[i].events & EPOLLOUT) /* connection completed */
           event_generate(ET_CONNECT, sock, 0);
@@ -291,12 +291,6 @@ engine_loop(struct Generators *gen)
 
       case SS_NOTSOCK:
       case SS_CONNECTED:
-        if (events[i].events & EPOLLIN)
-          event_generate((events[i].events & EPOLLHUP) ? ET_EOF : ET_READ, sock, 0);
-        if (events[i].events & EPOLLOUT)
-          event_generate(ET_WRITE, sock, 0);
-        break;
-
       case SS_DATAGRAM:
       case SS_CONNECTDG:
         if (events[i].events & EPOLLIN)
index e9441625bb297e7ad93235eb27b747829d0e89ac..8b76a160cab521c84c94000b3b7d76e9e37e9b6a 100644 (file)
@@ -245,7 +245,6 @@ struct IAuth *iauth_connect(char *host, unsigned short port, char *passwd, time_
     iauth_active = iauth;
     timer_init(&i_reconn_timer(iauth));
     i_reconnect(iauth) = reconnect;
-    s_fd(&i_socket(iauth)) = -1;
     iauth_reconnect(iauth);
   }
   if (passwd)
@@ -313,7 +312,7 @@ void iauth_close(struct IAuth *iauth)
   if (t_active(&i_request_timer(iauth)))
     timer_del(&i_request_timer(iauth));
   /* Disconnect from the server. */
-  if (s_fd(&i_socket(iauth)) != -1)
+  if (i_GetConnected(iauth))
     iauth_disconnect(iauth);
   /* Free memory. */
   MyFree(iauth);
@@ -400,7 +399,7 @@ static void iauth_disconnect(struct IAuth *iauth)
 {
   close(s_fd(&i_socket(iauth)));
   socket_del(&i_socket(iauth));
-  s_fd(&i_socket(iauth)) = -1;
+  i_ClrConnected(iauth);
 }
 
 /** DNS completion callback for an %IAuth connection.
@@ -411,11 +410,11 @@ static void iauth_dns_callback(void *vptr, struct DNSReply *he)
 {
   struct IAuth *iauth = vptr;
   if (!he) {
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: host lookup failed", i_host(iauth));
+    log_write(LS_IAUTH, L_NOTICE, 0, "IAuth connection to %s failed: host lookup failed", i_host(iauth));
   } else {
     memcpy(&i_addr(iauth).addr, &he->addr, sizeof(i_addr(iauth).addr));
     if (!irc_in_addr_valid(&i_addr(iauth).addr)) {
-      sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: host came back as unresolved", i_host(iauth));
+      log_write(LS_IAUTH, L_NOTICE, 0, "IAuth connection to %s failed: host came back as unresolved", i_host(iauth));
       return;
     }
     iauth_reconnect(iauth);
@@ -454,9 +453,12 @@ static void iauth_reconnect(struct IAuth *iauth)
   IOResult result;
   int fd;
 
-  if (s_fd(&i_socket(iauth)) != -1)
+  if (i_GetConnected(iauth)) {
     iauth_disconnect(iauth);
-  Debug((DEBUG_INFO, "IAuth attempt connection to %s port %p.", i_host(iauth), i_port(iauth)));
+    iauth_schedule_reconnect(iauth);
+    return;
+  }
+  log_write(LS_IAUTH, L_DEBUG, 0, "IAuth attempt connection to %s port %p.", i_host(iauth), i_port(iauth));
   if (!irc_in_addr_valid(&i_addr(iauth).addr)
       && !ircd_aton(&i_addr(iauth).addr, i_host(iauth))) {
     i_query(iauth).vptr = iauth;
@@ -466,27 +468,32 @@ static void iauth_reconnect(struct IAuth *iauth)
   }
   local = irc_in_addr_is_ipv4(&i_addr(iauth).addr) ? &VirtualHost_v4 : &VirtualHost_v6;
   fd = os_socket(local, SOCK_STREAM, "IAuth");
-  if (fd < 0)
+  if (fd < 0) {
+    iauth_schedule_reconnect(iauth);
     return;
+  }
   if (!os_set_sockbufs(fd, SERVER_TCP_WINDOW, SERVER_TCP_WINDOW)) {
-    close(fd);
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to set socket buffers: %s", strerror(errno));
-    return;
+    log_write(LS_IAUTH, L_WARNING, 0, "IAuth reconnect unable to set socket buffers: %s", strerror(errno));
+    goto failure;
   }
+  s_fd(&i_socket(iauth)) = fd;
   result = os_connect_nonb(fd, &i_addr(iauth));
   if (result == IO_FAILURE) {
-    close(fd);
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to initiate connection: %s", strerror(errno));
-    return;
+    log_write(LS_IAUTH, L_NOTICE, 0, "IAuth reconnect unable to initiate connection: %s", strerror(errno));
+    goto failure;
   }
-  s_fd(&i_socket(iauth)) = fd;
   if (!socket_add(&i_socket(iauth), iauth_sock_callback, iauth,
                   (result == IO_SUCCESS) ? SS_CONNECTED : SS_CONNECTING,
                   SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE, fd)) {
-    close(fd);
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to add socket: %s", strerror(errno));
-    return;
+    log_write(LS_IAUTH, L_WARNING, 0, "IAuth reconnect unable to add socket: %s", strerror(errno));
+    goto failure;
   }
+  return;
+failure:
+  close(fd);
+  i_ClrConnected(iauth);
+  iauth_schedule_reconnect(iauth);
+  return;
 }
 
 /** Read input from \a iauth.
@@ -500,9 +507,8 @@ static void iauth_read(struct IAuth *iauth)
   char readbuf[SERVER_TCP_WINDOW];
 
   length = 0;
-  if (IO_FAILURE == os_recv_nonb(s_fd(&i_socket(iauth)), readbuf, sizeof(readbuf), &length))
-    return;
-  if (length == 0) {
+  if (IO_FAILURE == os_recv_nonb(s_fd(&i_socket(iauth)), readbuf, sizeof(readbuf), &length)
+      || length == 0) {
       iauth_reconnect(iauth);
       return;
   }
@@ -619,13 +625,12 @@ static void iauth_sock_callback(struct Event *ev)
     i_ClrBlocked(iauth);
     iauth_write(iauth);
     break;
-  case ET_EOF:
-    iauth_disconnect(iauth);
-    break;
   case ET_ERROR:
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth socket error: %s", strerror(ev_data(ev)));
-    log_write(LS_SOCKET, L_ERROR, 0, "IAuth socket error: %s", strerror(ev_data(ev)));
+    log_write(LS_IAUTH, L_ERROR, 0, "IAuth socket error: %s", strerror(ev_data(ev)));
+    /* and fall through to the ET_EOF case */
+  case ET_EOF:
     iauth_disconnect(iauth);
+    iauth_schedule_reconnect(iauth);
     break;
   default:
     assert(0 && "Unrecognized event type");
@@ -642,7 +647,7 @@ static void iauth_request_ev(struct Event *ev)
 {
   /* TODO: this could probably be more intelligent */
   if (ev_type(ev) == ET_EXPIRE) {
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth request timed out; reconnecting");
+    log_write(LS_IAUTH, L_NOTICE, 0, "IAuth request timed out; reconnecting");
     iauth_reconnect(t_data(ev_timer(ev)));
   }
 }
@@ -693,6 +698,7 @@ int iauth_start_client(struct IAuth *iauth, struct Client *cptr)
   /* Allocate and initialize IAuthRequest struct. */
   if (!(iar = MyCalloc(1, sizeof(*iar))))
     return exit_client(cptr, cptr, &me, "IAuth memory allocation failed");
+  cli_iauth(cptr) = iar;
   iar->iar_next = &i_list_head(iauth);
   iar->iar_prev = i_list_head(iauth).iar_prev;
   iar->iar_client = cptr;
@@ -714,9 +720,11 @@ void iauth_exit_client(struct Client *cptr)
   if (cli_iauth(cptr)) {
     iauth_dispose_request(iauth_active, cli_iauth(cptr));
     cli_iauth(cptr) = NULL;
-  } else if (IsIAuthed(cptr) && i_GetIClass(iauth_active)) {
-    /* TODO: report quit to iauth */
   }
+  if (!i_GetConnected(iauth_active))
+    return;
+  iauth_send(iauth_active, "ExitUser %x", cptr);
+  iauth_write(iauth_active);
 }
 
 /** Find pending request with a particular ID.
index 8f5ac69d9223ea67f6fec7ad33771323bab395dc..6251842b761c509c273280184c65e3fa98145cb7 100644 (file)
@@ -162,8 +162,8 @@ static struct LogDesc {
   S(OPER, -1, SNO_OLDREALOP),
   S(RESOLVER, -1, 0),
   S(SOCKET, -1, 0),
+  S(IAUTH, -1, SNO_NETWORK),
   S(DEBUG, -1, SNO_DEBUG),
-  S(OLDLOG, -1, 0),
 #undef S
   { LS_LAST_SYSTEM, 0, 0, -1, 0, -1, 0 }
 };
index a55c974a3847c1c6dc893ccb430d1f5ebda8bdeb..96dd2d09b40968f9195a368da1263ec14dbc12a6 100644 (file)
@@ -245,9 +245,8 @@ static void exit_one_client(struct Client* bcptr, const char* comment)
       --UserStats.opers;
     if (MyConnect(bcptr))
       Count_clientdisconnects(bcptr, UserStats);
-    else {
+    else
       Count_remoteclientquits(UserStats, bcptr);
-    }
   }
   else if (IsServer(bcptr))
   {
@@ -284,7 +283,7 @@ static void exit_one_client(struct Client* bcptr, const char* comment)
     /* bcptr->user->server->serv->client_list[IndexYXX(bcptr)] = NULL; */
     RemoveYXXClient(cli_user(bcptr)->server, cli_yxx(bcptr));
     if (IsIAuthed(bcptr) || cli_iauth(bcptr))
-        iauth_exit_client(bcptr);
+      iauth_exit_client(bcptr);
   }
 
   /* Remove bcptr from the client list */