Fix display with %hu format.
[ircu2.10.12-pk.git] / ircd / ircd_auth.c
index 7487fd5156cc7e91205df637c373f1f7c3178cd5..c38bf5ce1a9938e56687232713760e2f57e7beba 100644 (file)
@@ -82,7 +82,6 @@ struct IAuth {
   struct Timer i_reconn_timer;          /**< when to reconnect the connection */
   struct Timer i_request_timer;         /**< when the current request times out */
   struct IAuthFlags i_flags;            /**< connection state/status/flags */
-  struct DNSQuery i_query;              /**< DNS lookup for iauth server */
   unsigned int i_recvM;                 /**< messages received */
   unsigned int i_sendM;                 /**< messages sent */
   unsigned int i_recvK;                 /**< kilobytes received */
@@ -243,6 +242,7 @@ struct IAuth *iauth_connect(char *host, unsigned short port, char *passwd, time_
     memset(&i_addr(iauth), 0, sizeof(i_addr(iauth)));
     i_port(iauth) = port;
     iauth_active = iauth;
+    timer_init(&i_reconn_timer(iauth));
     i_reconnect(iauth) = reconnect;
     iauth_reconnect(iauth);
   }
@@ -311,7 +311,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);
@@ -365,7 +365,7 @@ static void iauth_protocol_violation(struct IAuth *iauth, const char *format, ..
   assert(format != 0);
   vd.vd_format = format;
   va_start(vd.vd_args, format);
-  sendwallto_group_butone(&me, WALL_DESYNCH, NULL, "IAuth protocol violation: %v", &vd);
+  sendto_opmask_butone(NULL, SNO_CONNEXIT, "IAuth protocol violation: %v", &vd);
   va_end(vd.vd_args);
 }
 
@@ -398,22 +398,22 @@ 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.
  * @param[in] vptr Pointer to the IAuth struct.
  * @param[in] he DNS reply parameters.
  */
-static void iauth_dns_callback(void *vptr, struct DNSReply *he)
+static void iauth_dns_callback(void *vptr, const struct irc_in_addr *addr, const char *h_name)
 {
   struct IAuth *iauth = vptr;
-  if (!he) {
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: host lookup failed", i_host(iauth));
+  if (!addr) {
+    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));
+    memcpy(&i_addr(iauth).addr, 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);
@@ -435,9 +435,12 @@ static void iauth_reconnect_ev(struct Event *ev)
 static void iauth_schedule_reconnect(struct IAuth *iauth)
 {
   struct Timer *timer;
-  assert(!t_active(&i_reconn_timer(iauth)));
-  timer = timer_init(&i_reconn_timer(iauth));
-  timer_add(timer, iauth_reconnect_ev, iauth, TT_RELATIVE, i_reconnect(iauth));
+  timer = &i_reconn_timer(iauth);
+  if (t_onqueue(timer))
+    timer_chg(timer, TT_RELATIVE, i_reconnect(iauth));
+  else
+    timer_add(&i_reconn_timer(iauth), iauth_reconnect_ev,
+              iauth, TT_RELATIVE, i_reconnect(iauth));
 }
 
 /** Initiate a (re-)connection to \a iauth.
@@ -449,36 +452,45 @@ static void iauth_reconnect(struct IAuth *iauth)
   IOResult result;
   int fd;
 
-  Debug((DEBUG_INFO, "IAuth attempt connection to %s port %p.", i_host(iauth), i_port(iauth)));
+  if (i_GetConnected(iauth)) {
+    iauth_disconnect(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;
-    i_query(iauth).callback = iauth_dns_callback;
-    gethost_byname(i_host(iauth), &i_query(iauth));
+    gethost_byname(i_host(iauth), iauth_dns_callback, iauth);
     return;
   }
   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;
   }
   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.
@@ -492,8 +504,11 @@ 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 (IO_FAILURE == os_recv_nonb(s_fd(&i_socket(iauth)), readbuf, sizeof(readbuf), &length)
+      || length == 0) {
+      iauth_reconnect(iauth);
+      return;
+  }
   i_recvB(iauth) += length;
   if (i_recvB(iauth) > 1023) {
     i_recvK(iauth) += i_recvB(iauth) >> 10;
@@ -607,13 +622,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");
@@ -630,7 +644,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)));
   }
 }
@@ -681,6 +695,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;
@@ -702,8 +717,10 @@ 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 (iauth_active && i_GetConnected(iauth_active)) {
+    iauth_send(iauth_active, "ExitUser %x", cptr);
+    iauth_write(iauth_active);
   }
 }
 
@@ -734,7 +751,7 @@ static struct IAuthRequest *iauth_find_request(struct IAuth *iauth, char *id)
 static void iauth_dispose_request(struct IAuth *iauth, struct IAuthRequest *iar)
 {
   assert(iar->iar_client != NULL);
-  if (iar->iar_timed)
+  if (iar->iar_timed && t_active(&i_request_timer(iauth)))
     timer_del(&i_request_timer(iauth));
   cli_iauth(iar->iar_client) = NULL;
   iar->iar_prev->iar_next = iar->iar_next;