Make IAuth protocol work again and add a bit of debugging to it.
[ircu2.10.12-pk.git] / ircd / ircd_auth.c
index f15063ca3625a738d56467b8bc746206b407abb5..e189a323279195394247741d26ce0f3c87b92ce3 100644 (file)
@@ -35,6 +35,7 @@
 #include "msgq.h"
 #include "res.h"
 #include "s_bsd.h"
+#include "s_debug.h"
 #include "s_misc.h"
 #include "s_user.h"
 #include "send.h"
@@ -47,6 +48,9 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
 
 struct IAuthRequest {
   struct IAuthRequest *iar_prev;        /* previous request struct */
@@ -86,8 +90,7 @@ struct IAuth {
   char i_buffer[BUFSIZE+1];             /* partial unprocessed line from server */
   char i_passwd[PASSWDLEN+1];           /* password for connection */
   char i_host[HOSTLEN+1];               /* iauth server hostname */
-  in_addr_t i_addr;                     /* iauth server ip address */
-  unsigned short i_port;                /* iauth server port */
+  struct irc_sockaddr i_addr;           /* iauth server ip address and port */
   struct IAuth *i_next;                 /* next connection in list */
 };
 
@@ -130,7 +133,7 @@ struct IAuth {
 #define i_passwd(iauth) ((iauth)->i_passwd)
 #define i_host(iauth) ((iauth)->i_host)
 #define i_addr(iauth) ((iauth)->i_addr)
-#define i_port(iauth) ((iauth)->i_port)
+#define i_port(iauth) ((iauth)->i_addr.port)
 #define i_next(iauth) ((iauth)->i_next)
 
 struct IAuthCmd {
@@ -178,9 +181,8 @@ struct IAuth *iauth_connect(char *host, unsigned short port, char *passwd, time_
     i_list_head(iauth).iar_next = &i_list_head(iauth);
     msgq_init(&i_sendQ(iauth));
     ircd_strncpy(i_host(iauth), host, HOSTLEN);
+    memset(&i_addr(iauth), 0, sizeof(i_addr(iauth)));
     i_port(iauth) = port;
-    i_addr(iauth) = INADDR_NONE;
-    i_next(iauth) = iauth_active;
     iauth_active = iauth;
     i_reconnect(iauth) = reconnect;
     iauth_reconnect(iauth);
@@ -190,6 +192,7 @@ struct IAuth *iauth_connect(char *host, unsigned short port, char *passwd, time_
   else
     i_passwd(iauth)[0] = '\0';
   i_timeout(iauth) = timeout;
+  i_SetIClass(iauth);
   return iauth;
 }
 
@@ -254,7 +257,7 @@ void iauth_close(struct IAuth *iauth)
 void iauth_close_unused(void)
 {
   struct IAuth *prev, *iauth, *next;
-  
+
   for (prev = NULL, iauth = iauth_active; iauth; iauth = next) {
     next = i_next(iauth);
     if (i_GetClosing(iauth)) {
@@ -325,13 +328,10 @@ 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));
-  } else if (he->h_addrtype != AF_INET) {
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: bad host type %d", i_host(iauth), he->h_addrtype);
   } else {
-    struct sockaddr_in *sin = (struct sockaddr_in*)&he->addr;
-    i_addr(iauth) = sin->sin_addr.s_addr;
-    if (INADDR_NONE == i_addr(iauth)) {
-      sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: host came back as INADDR_NONE", i_host(iauth));
+    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));
       return;
     }
     iauth_reconnect(iauth);
@@ -354,46 +354,26 @@ static void iauth_schedule_reconnect(struct IAuth *iauth)
 
 static void iauth_reconnect(struct IAuth *iauth)
 {
-  extern struct sockaddr_in VirtualHost;
-  struct sockaddr_in sin;
   IOResult result;
   int fd;
 
-  if (INADDR_NONE == i_addr(iauth)) {
-    i_addr(iauth) = inet_addr(i_host(iauth));
-    if (INADDR_NONE == i_addr(iauth)) {
-      i_query(iauth).vptr = iauth;
-      i_query(iauth).callback = iauth_dns_callback;
-      gethost_byname(i_host(iauth), &i_query(iauth));
-      return;
-    }
-  }
-  fd = socket(AF_INET, SOCK_STREAM, 0);
-  if (0 > fd) {
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to allocate socket: %s", strerror(errno));
+  Debug((DEBUG_INFO, "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));
     return;
   }
-  if (feature_bool(FEAT_VIRTUAL_HOST)
-      && bind(fd, (struct sockaddr*)&VirtualHost, sizeof(VirtualHost)) != 0) {
-    close(fd);
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to bind vhost: %s", strerror(errno));
+  fd = os_socket(&VirtualHost, SOCK_STREAM, "IAuth");
+  if (fd < 0)
     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;
   }
-  if (!os_set_nonblocking(fd)) {
-    close(fd);
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to make socket non-blocking: %s", strerror(errno));
-    return;
-  }
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_family = AF_INET;
-  sin.sin_addr.s_addr = i_addr(iauth);
-  sin.sin_port = htons(i_port(iauth));
-  result = os_connect_nonb(fd, &sin);
+  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));
@@ -554,8 +534,10 @@ static void iauth_send_request(struct IAuth *iauth, struct IAuthRequest *iar)
   struct Client *client;
 
   /* If iauth is not connected, we must defer the request. */
-  if (!i_GetConnected(iauth))
+  if (!i_GetConnected(iauth)) {
+    Debug((DEBUG_SEND, "IAuth deferring request for %s because we are not connected.", cli_name(iar->iar_client)));
     return;
+  }
 
   /* If no timed request, set up expiration timer. */
   if (!t_active(&i_request_timer(iauth))) {