Просмотр исходного кода

* Link over unix domain socket to localhub

Bryan Drewery 16 лет назад
Родитель
Сommit
d779e9dec9
6 измененных файлов с 91 добавлено и 41 удалено
  1. 58 24
      src/botnet.c
  2. 1 0
      src/conf.c
  3. 1 0
      src/conf.h
  4. 24 16
      src/net.c
  5. 2 0
      src/net.h
  6. 5 1
      src/users.c

+ 58 - 24
src/botnet.c

@@ -948,6 +948,7 @@ int botunlink(int idx, const char *nick, const char *reason)
 }
 
 static void botlink_dns_callback(int, void *, const char *, bd::Array<bd::String>);
+static void botlink_real(int);
 
 /* Link to another bot
  */
@@ -976,10 +977,16 @@ int botlink(char *linker, int idx, char *nick)
 	return 0;
       }
     }
+
+    bool unix_domain = 0;
+
+    if (!conf.bot->hub && !conf.bot->localhub && !strcmp(nick, conf.localhub))
+      unix_domain = 1;
+
     /* Address to connect to is in 'info' */
     struct bot_addr *bi = (struct bot_addr *) get_user(&USERENTRY_BOTADDR, u);
 
-    if (!bi || !strlen(bi->address) || !bi->telnet_port || (bi->telnet_port <= 0)) {
+    if (!unix_domain && (!bi || !strlen(bi->address) || !bi->telnet_port || (bi->telnet_port <= 0))) {
       if (idx >= 0) {
 	dprintf(idx, "Invalid telnet address:port stored for '%s'.\n", nick);
 	dprintf(idx, "Use: %schaddr %s <address>:<port#>[/<relay-port#>]\n", (dcc[idx].u.chat->channel >= 0) ? settings.dcc_prefix : "", nick);
@@ -990,30 +997,47 @@ int botlink(char *linker, int idx, char *nick)
     } else {
       correct_handle(nick);
 
-      if (idx > -2)
-	putlog(LOG_BOTS, "*", "Linking to %s at %s:%d ...", nick,
-	       bi->address, bi->telnet_port);
+      char *address = NULL;
+      port_t port = 0;
+
+      if (unix_domain) {
+        address = conf.localhub_socket;
+      } else if (bi) {
+        address = bi->address;
+        port = bi->telnet_port;
+      }
+
+      if (idx > -2) {
+        if (port)
+          putlog(LOG_BOTS, "*", "Linking to %s at %s:%d ...", nick, address, port);
+        else
+          putlog(LOG_BOTS, "*", "Linking to %s at %s ...", nick, address);
+      }
 
       i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
 
       dcc[i].timeval = now;
-      dcc[i].port = bi->telnet_port;
+      dcc[i].port = port;
       dcc[i].user = u;
       strlcpy(dcc[i].nick, nick, NICKLEN);
-      strlcpy(dcc[i].host, bi->address, UHOSTLEN);
+      strlcpy(dcc[i].host, address, UHOSTLEN);
       dcc[i].u.dns->cptr = strdup(linker);
       dcc[i].u.dns->ibuf = idx;
       dcc[i].bot = 1;
 
-      int dns_id = egg_dns_lookup(bi->address, 20, botlink_dns_callback, (void *) (long)i);
-       /* dns_id 
-        * -1 means it was cached and the callback already called
-        * -2 means it's already being looked up.. try again later .. */
-      if (dns_id >= 0)
-        dcc[i].dns_id = dns_id;
-      else if (dns_id == -2) {
-        lostdcc(i);
-        return 0;
+      if (unix_domain) {
+        botlink_real(i);
+      } else {
+        int dns_id = egg_dns_lookup(address, 20, botlink_dns_callback, (void *) (long)i);
+         /* dns_id
+          * -1 means it was cached and the callback already called
+          * -2 means it's already being looked up.. try again later .. */
+        if (dns_id >= 0)
+          dcc[i].dns_id = dns_id;
+        else if (dns_id == -2) {
+          lostdcc(i);
+          return 0;
+        }
       }
      
       return 1;
@@ -1031,13 +1055,9 @@ static void botlink_dns_callback(int id, void *client_data, const char *host, bd
   if (!valid_dns_id(i, id))
     return;
 
-  int idx = -1;
-  char *linker = NULL;
-
-  if (valid_idx(i)) {
-    idx = dcc[i].u.dns->ibuf;
-    linker = strdup(dcc[i].u.dns->cptr);
-  }
+//  if (valid_idx(i)) {
+//    idx = dcc[i].u.dns->ibuf;
+//  }
 
   if (!ips.size()) {
     lostdcc(i);
@@ -1045,6 +1065,15 @@ static void botlink_dns_callback(int id, void *client_data, const char *host, bd
   }
 
   dcc[i].addr = inet_addr(bd::String(ips[0]).c_str());
+  strlcpy(dcc[i].host, bd::String(ips[0]).c_str(), UHOSTLEN);
+
+  botlink_real(i);
+}
+
+static void botlink_real(int i)
+{
+  int idx = dcc[i].u.dns->ibuf;
+  char *linker = strdup(dcc[i].u.dns->cptr);
 
   changeover_dcc(i, &DCC_FORK_BOT, sizeof(struct bot_info));
   dcc[i].timeval = now;
@@ -1057,7 +1086,12 @@ static void botlink_dns_callback(int id, void *client_data, const char *host, bd
 
   dcc[i].u.bot->port = dcc[i].port;             /* Remember where i started */
 #ifdef USE_IPV6
-  dcc[i].sock = getsock(SOCK_STRONGCONN, is_dotted_ip(bd::String(ips[0]).c_str()));
+  int af_type;
+  if (dcc[i].port)
+    af_type = is_dotted_ip(dcc[i].host);
+  else
+    af_type = AF_UNIX;
+  dcc[i].sock = getsock(SOCK_STRONGCONN, af_type);
 #else
   dcc[i].sock = getsock(SOCK_STRONGCONN);
 #endif /* USE_IPV6 */
@@ -1065,7 +1099,7 @@ static void botlink_dns_callback(int id, void *client_data, const char *host, bd
 //  if (dcc[i].sock > 0)
 //    identd_open();                      /* will be closed when an ident is replied. */
 
-  if (dcc[i].sock < 0 || open_telnet_raw(dcc[i].sock, bd::String(ips[0]).c_str(), dcc[i].port, 0, 1) < 0)
+  if (dcc[i].sock < 0 || open_telnet_raw(dcc[i].sock, dcc[i].host, dcc[i].port, 0, 1) < 0)
     failed_link(i);
   else { /* let's attempt to initiate SSL before ANYTHING else... */
     dcc[i].ssl = 0;

+ 1 - 0
src/conf.c

@@ -484,6 +484,7 @@ conf_addbot(const char *nick, const char *ip, const char *host, const char *ip6)
   if (!conf.localhub && !bot->hub && !bot->disabled) {
     bot->localhub = 1;          /* first bot */
     conf.localhub = strdup(bot->nick);
+    conf.localhub_socket = strdup("/tmp/wraith-test");
   }
 
   //Add this bot to the userlist

+ 1 - 0
src/conf.h

@@ -34,6 +34,7 @@ typedef struct conf_b {
   int uid;
   int autocron;         /* should the bot auto crontab itself? */
   char *localhub;	/* my localhub */
+  char *localhub_socket;	/* my localhub unix socket */
   char *datadir;
   char *username;       /* shell username */
   char *homedir;        /* homedir */

+ 24 - 16
src/net.c

@@ -565,23 +565,31 @@ int open_telnet_raw(int sock, const char *ipIn, port_t sport, bool proxy_on, int
     port = sport;
   }
 
-  /* figure out which ip to bind to locally (v4 or v6) based on what the host ip is .. */
-  if ((is_resolved = is_dotted_ip(ip))) {	/* already resolved */
-  
-    /* bind to our cached ip for v4/v6 depending on what the ip is */
-    initialize_sockaddr(is_resolved, NULL, 0, &so);
+  size_t socklen;
+  if (sport) {
+    /* figure out which ip to bind to locally (v4 or v6) based on what the host ip is .. */
+    if ((is_resolved = is_dotted_ip(ip))) {	/* already resolved */
+
+      /* bind to our cached ip for v4/v6 depending on what the ip is */
+      initialize_sockaddr(is_resolved, NULL, 0, &so);
+
+      if (bind(sock, &so.sa, SIZEOF_SOCKADDR(so)) < 0) {
+        putlog(LOG_DEBUG, "*", "Failed to bind to socket %d: %s", sock, strerror(errno));
+        killsock(sock);
+        return -1;
+      }
 
-    if (bind(sock, &so.sa, SIZEOF_SOCKADDR(so)) < 0) {
-      putlog(LOG_DEBUG, "*", "Failed to bind to socket %d: %s", sock, strerror(errno));
-      killsock(sock);
+      /* initialize so for connect using the host/port */
+      initialize_sockaddr(is_resolved, ip, port, &so);
+    } else {	/* if not resolved, resolve it with blocking calls.. (shouldn't happen ever) */
+      sdprintf("WARNING: open_telnet_raw(%s,%d) was passed an unresolved hostname.", ip, port);
       return -1;
     }
-
-    /* initialize so for connect using the host/port */
-    initialize_sockaddr(is_resolved, ip, port, &so);
-  } else {	/* if not resolved, resolve it with blocking calls.. (shouldn't happen ever) */
-    sdprintf("WARNING: open_telnet_raw(%s,%d) was passed an unresolved hostname.", ip, port);
-    return -1;
+    socklen = SIZEOF_SOCKADDR(so);
+  } else { // Unix domain socket
+    so.sun.sun_family = AF_UNIX;
+    strcpy(so.sun.sun_path, ip);
+    socklen = strlen(so.sun.sun_path) + sizeof(so.sun.sun_family);
   }
 
   for (int i = 0; i < MAXSOCKS; i++) {
@@ -593,13 +601,13 @@ int open_telnet_raw(int sock, const char *ipIn, port_t sport, bool proxy_on, int
     }
   }
 
-  if (identd)
+  if (identd && sport) //Only open identd if not a unix domain socket
     identd_open(myipstr(is_resolved), ipIn, identd);
 
   int rc = -1;
 
   /* make the connect attempt */
-  rc = connect(sock, &so.sa, SIZEOF_SOCKADDR(so));
+  rc = connect(sock, (struct sockaddr *)&so.sa, socklen);
 
   if (rc < 0) {    
     if (errno == EINPROGRESS) {

+ 2 - 0
src/net.h

@@ -8,6 +8,7 @@
 #include "types.h"
 #include <netinet/in.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <setjmp.h>
 
 namespace bd {
@@ -66,6 +67,7 @@ union sockaddr_union {			/* replaced by sockname_t */
 #ifdef USE_IPV6
   struct sockaddr_in6 sin6;
 #endif /* USE_IPV6 */
+  struct sockaddr_un sun;
 };
 
 /* This is used by the net module to keep track of sockets and what's

+ 5 - 1
src/users.c

@@ -1199,8 +1199,12 @@ void autolink_cycle(char *start)
 {
   if (conf.bot->hub)
     autolink_cycle_hub(start);
-  else
+  else if (conf.bot->localhub)
     autolink_cycle_leaf(start);
+  else { //Connect to the localhub
+    sdprintf("need to link to my localhub: %s\n", conf.localhub);
+    botlink("", -3, conf.localhub);
+  }
 }