ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/src/server.c
(Generate patch)

Comparing ircd-hybrid-8/src/s_serv.c (file contents):
Revision 1302 by michael, Wed Mar 21 17:48:54 2012 UTC vs.
Revision 1389 by michael, Tue May 1 13:08:29 2012 UTC

# Line 43 | Line 43
43   #include "numeric.h"
44   #include "packet.h"
45   #include "irc_res.h"
46 < #include "s_conf.h"
46 > #include "conf.h"
47   #include "s_serv.h"
48 < #include "s_log.h"
48 > #include "log.h"
49 > #include "s_misc.h"
50   #include "s_user.h"
51   #include "send.h"
52   #include "memory.h"
# Line 61 | Line 62 | static void send_tb(struct Client *clien
62  
63   static CNCB serv_connect_callback;
64  
64 static void start_io(struct Client *);
65   static void burst_members(struct Client *, struct Channel *);
66  
67   /*
# Line 81 | Line 81 | write_links_file(void* notused)
81    MessageFileLine *newMessageLine = 0;
82    MessageFile *MessageFileptr;
83    const char *p;
84 <  FBFILE *file;
84 >  FILE *file;
85    char buff[512];
86    dlink_node *ptr;
87  
88    MessageFileptr = &ConfigFileEntry.linksfile;
89  
90 <  if ((file = fbopen(MessageFileptr->fileName, "w")) == NULL)
90 >  if ((file = fopen(MessageFileptr->fileName, "w")) == NULL)
91      return;
92  
93    for (mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr)
# Line 101 | Line 101 | write_links_file(void* notused)
101  
102    DLINK_FOREACH(ptr, global_serv_list.head)
103    {
104 <    size_t nbytes = 0;
105 <    struct Client *target_p = ptr->data;
104 >    const struct Client *target_p = ptr->data;
105  
106      /* skip ourselves, we send ourselves in /links */
107      if (IsMe(target_p))
# Line 133 | Line 132 | write_links_file(void* notused)
132       */
133      assert(strlen(target_p->name) + strlen(me.name) + 6 + strlen(p) <=
134              MESSAGELINELEN);
135 <    ircsprintf(newMessageLine->line, "%s %s :1 %s",
136 <               target_p->name, me.name, p);
135 >    snprintf(newMessageLine->line, sizeof(newMessageLine->line), "%s %s :1 %s",
136 >             target_p->name, me.name, p);
137      newMessageLine->next = NULL;
138  
139      if (MessageFileptr->contentsOfFile)
# Line 149 | Line 148 | write_links_file(void* notused)
148        currentMessageLine = newMessageLine;
149      }
150  
151 <    nbytes = ircsprintf(buff, "%s %s :1 %s\n", target_p->name, me.name, p);
152 <    fbputs(buff, file, nbytes);
151 >    snprintf(buff, sizeof(buff), "%s %s :1 %s\n", target_p->name, me.name, p);
152 >    fputs(buff, file);
153    }
154  
155 <  fbclose(file);
155 >  fclose(file);
156   }
157  
158   /* hunt_server()
# Line 184 | Line 183 | hunt_server(struct Client *client_p, str
183    dlink_node *ptr;
184    int wilds;
185  
186 <  /* Assume it's me, if no server
187 <   */
188 <  if (parc <= server || EmptyString(parv[server]) ||
189 <      match(me.name, parv[server]) ||
190 <      match(parv[server], me.name) ||
191 <      !strcmp(parv[server], me.id))
193 <    return(HUNTED_ISME);
186 >  /* Assume it's me, if no server */
187 >  if (parc <= server || EmptyString(parv[server]))
188 >    return HUNTED_ISME;
189 >
190 >  if (!strcmp(parv[server], me.id) || match(parv[server], me.name))
191 >    return HUNTED_ISME;
192  
193    /* These are to pickup matches that would cause the following
194     * message to go in the wrong direction while doing quick fast
# Line 326 | Line 324 | try_connections(void *unused)
324        confrq = DEFAULT_CONNECTFREQUENCY;
325      else
326      {
327 <      confrq = ConFreq(cltmp);
328 <      if (confrq < MIN_CONN_FREQ )
327 >      confrq = cltmp->con_freq;
328 >      if (confrq < MIN_CONN_FREQ)
329          confrq = MIN_CONN_FREQ;
330      }
331  
# Line 339 | Line 337 | try_connections(void *unused)
337      if (hash_find_server(conf->name) != NULL)
338        continue;
339  
340 <    if (CurrUserCount(cltmp) < MaxTotal(cltmp))
340 >    if (cltmp->curr_user_count < cltmp->max_total)
341      {
342        /* Go to the end of the list, if not already last */
343        if (ptr->next != NULL)
# Line 459 | Line 457 | check_server(const char *name, struct Cl
457  
458    attach_conf(client_p, server_conf);
459  
462  /* Now find all leaf or hub config items for this server */
463  DLINK_FOREACH(ptr, hub_items.head)
464  {
465    conf = ptr->data;
466
467    if (!match(name, conf->name))
468      continue;
469    attach_conf(client_p, conf);
470  }
471
472  DLINK_FOREACH(ptr, leaf_items.head)
473  {
474    conf = ptr->data;
475
476    if (!match(name, conf->name))
477      continue;
478    attach_conf(client_p, conf);
479  }
480
460    server_aconf = map_to_conf(server_conf);
461  
462    if (!IsConfTopicBurst(server_aconf))
# Line 496 | Line 475 | check_server(const char *name, struct Cl
475      {
476   #ifdef IPV6
477        case AF_INET6:
478 <        v6 = (struct sockaddr_in6 *)&aconf->ipnum;
478 >        v6 = (struct sockaddr_in6 *)&aconf->addr;
479  
480          if (IN6_IS_ADDR_UNSPECIFIED(&v6->sin6_addr))
481 <          memcpy(&aconf->ipnum, &client_p->localClient->ip, sizeof(struct irc_ssaddr));
481 >          memcpy(&aconf->addr, &client_p->localClient->ip, sizeof(struct irc_ssaddr));
482          break;
483   #endif
484        case AF_INET:
485 <        v4 = (struct sockaddr_in *)&aconf->ipnum;
485 >        v4 = (struct sockaddr_in *)&aconf->addr;
486  
487          if (v4->sin_addr.s_addr == INADDR_NONE)
488 <          memcpy(&aconf->ipnum, &client_p->localClient->ip, sizeof(struct irc_ssaddr));
488 >          memcpy(&aconf->addr, &client_p->localClient->ip, sizeof(struct irc_ssaddr));
489          break;
490      }
491    }
# Line 689 | Line 668 | sendnick_TS(struct Client *client_p, str
668                   target_p->servptr->name, target_p->info);
669    }
670  
671 <  if (IsConfAwayBurst((struct AccessItem *)map_to_conf(client_p->serv->sconf)))
671 >  if (IsConfAwayBurst((struct AccessItem *)map_to_conf(client_p->localClient->confs.head->data)))
672      if (!EmptyString(target_p->away))
673        sendto_one(client_p, ":%s AWAY :%s", target_p->name,
674                   target_p->away);
# Line 756 | Line 735 | server_estab(struct Client *client_p)
735    const char *inpath;
736    static char inpath_ip[HOSTLEN * 2 + USERLEN + 6];
737    dlink_node *ptr;
738 + #ifdef HAVE_LIBCRYPTO
739 +  const COMP_METHOD *compression = NULL, *expansion = NULL;
740 + #endif
741  
742    assert(client_p != NULL);
743  
# Line 869 | Line 851 | server_estab(struct Client *client_p)
851    /* fixing eob timings.. -gnp */
852    client_p->localClient->firsttime = CurrentTime;
853  
872
854    if (find_matching_name_conf(SERVICE_TYPE, client_p->name, NULL, NULL, 0))
855      AddFlag(client_p, FLAGS_SERVICE);
856  
857    /* Show the real host/IP to admins */
858 <  sendto_realops_flags(UMODE_ALL, L_ADMIN,
859 <                       "Link with %s established: (%s) link",
860 <                       inpath_ip,show_capabilities(client_p));
861 <  /* Now show the masked hostname/IP to opers */
862 <  sendto_realops_flags(UMODE_ALL, L_OPER,
882 <                       "Link with %s established: (%s) link",
883 <                       inpath,show_capabilities(client_p));
884 <  ilog(LOG_TYPE_IRCD, "Link with %s established: (%s) link",
885 <       inpath_ip, show_capabilities(client_p));
858 > #ifdef HAVE_LIBCRYPTO
859 >  if (client_p->localClient->fd.ssl)
860 >  {
861 >    compression = SSL_get_current_compression(client_p->localClient->fd.ssl);
862 >    expansion   = SSL_get_current_expansion(client_p->localClient->fd.ssl);
863  
864 <  client_p->serv->sconf = conf;
864 >    sendto_realops_flags(UMODE_ALL, L_ADMIN,
865 >                         "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)",
866 >                         inpath_ip, ssl_get_cipher(client_p->localClient->fd.ssl),
867 >                         compression ? SSL_COMP_get_name(compression) : "NONE",
868 >                         expansion ? SSL_COMP_get_name(expansion) : "NONE",
869 >                         show_capabilities(client_p));
870 >    /* Now show the masked hostname/IP to opers */
871 >    sendto_realops_flags(UMODE_ALL, L_OPER,
872 >                         "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)",
873 >                         inpath, ssl_get_cipher(client_p->localClient->fd.ssl),
874 >                         compression ? SSL_COMP_get_name(compression) : "NONE",
875 >                         expansion ? SSL_COMP_get_name(expansion) : "NONE",
876 >                         show_capabilities(client_p));
877 >    ilog(LOG_TYPE_IRCD, "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)",
878 >         inpath_ip, ssl_get_cipher(client_p->localClient->fd.ssl),
879 >         compression ? SSL_COMP_get_name(compression) : "NONE",
880 >         expansion ? SSL_COMP_get_name(expansion) : "NONE",
881 >         show_capabilities(client_p));
882 >  }
883 >  else
884 > #endif
885 >  {
886 >    sendto_realops_flags(UMODE_ALL, L_ADMIN,
887 >                         "Link with %s established: (Capabilities: %s)",
888 >                         inpath_ip,show_capabilities(client_p));
889 >    /* Now show the masked hostname/IP to opers */
890 >    sendto_realops_flags(UMODE_ALL, L_OPER,
891 >                         "Link with %s established: (Capabilities: %s)",
892 >                         inpath,show_capabilities(client_p));
893 >    ilog(LOG_TYPE_IRCD, "Link with %s established: (Capabilities: %s)",
894 >         inpath_ip, show_capabilities(client_p));
895 >  }
896  
897    fd_note(&client_p->localClient->fd, "Server: %s", client_p->name);
898  
# Line 1154 | Line 1162 | serv_connect(struct AccessItem *aconf, s
1162    conf = unmap_conf_item(aconf);
1163  
1164    /* log */
1165 <  getnameinfo((struct sockaddr *)&aconf->ipnum, aconf->ipnum.ss_len,
1165 >  getnameinfo((struct sockaddr *)&aconf->addr, aconf->addr.ss_len,
1166                buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
1167    ilog(LOG_TYPE_IRCD, "Connect to %s[%s] @%s", aconf->user, aconf->host,
1168         buf);
# Line 1205 | Line 1213 | serv_connect(struct AccessItem *aconf, s
1213    strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost));
1214  
1215    /* create a socket for the server connection */
1216 <  if (comm_open(&client_p->localClient->fd, aconf->ipnum.ss.ss_family,
1216 >  if (comm_open(&client_p->localClient->fd, aconf->addr.ss.ss_family,
1217                  SOCK_STREAM, 0, NULL) < 0)
1218    {
1219      /* Eek, failure to create the socket */
# Line 1260 | Line 1268 | serv_connect(struct AccessItem *aconf, s
1268    switch (aconf->aftype)
1269    {
1270      case AF_INET:
1271 <      v4 = (struct sockaddr_in*)&aconf->my_ipnum;
1271 >      v4 = (struct sockaddr_in*)&aconf->bind;
1272        if (v4->sin_addr.s_addr != 0)
1273        {
1274          struct irc_ssaddr ipn;
1275          memset(&ipn, 0, sizeof(struct irc_ssaddr));
1276          ipn.ss.ss_family = AF_INET;
1277          ipn.ss_port = 0;
1278 <        memcpy(&ipn, &aconf->my_ipnum, sizeof(struct irc_ssaddr));
1278 >        memcpy(&ipn, &aconf->bind, sizeof(struct irc_ssaddr));
1279          comm_connect_tcp(&client_p->localClient->fd, aconf->host, aconf->port,
1280                           (struct sockaddr *)&ipn, ipn.ss_len,
1281                           serv_connect_callback, client_p, aconf->aftype,
# Line 1298 | Line 1306 | serv_connect(struct AccessItem *aconf, s
1306          struct sockaddr_in6 *v6conf;
1307  
1308          memset(&ipn, 0, sizeof(struct irc_ssaddr));
1309 <        v6conf = (struct sockaddr_in6 *)&aconf->my_ipnum;
1309 >        v6conf = (struct sockaddr_in6 *)&aconf->bind;
1310          v6 = (struct sockaddr_in6 *)&ipn;
1311  
1312          if (memcmp(&v6conf->sin6_addr, &v6->sin6_addr,
1313                     sizeof(struct in6_addr)) != 0)
1314          {
1315 <          memcpy(&ipn, &aconf->my_ipnum, sizeof(struct irc_ssaddr));
1315 >          memcpy(&ipn, &aconf->bind, sizeof(struct irc_ssaddr));
1316            ipn.ss.ss_family = AF_INET6;
1317            ipn.ss_port = 0;
1318            comm_connect_tcp(&client_p->localClient->fd,
# Line 1335 | Line 1343 | serv_connect(struct AccessItem *aconf, s
1343    return (1);
1344   }
1345  
1346 + #ifdef HAVE_LIBCRYPTO
1347 + static void
1348 + finish_ssl_server_handshake(struct Client *client_p)
1349 + {
1350 +  struct ConfItem *conf=NULL;
1351 +  struct AccessItem *aconf=NULL;
1352 +
1353 +  conf = find_conf_name(&client_p->localClient->confs,
1354 +                        client_p->name, SERVER_TYPE);
1355 +  if (conf == NULL)
1356 +  {
1357 +    sendto_realops_flags(UMODE_ALL, L_ADMIN,
1358 +                         "Lost connect{} block for %s", get_client_name(client_p, HIDE_IP));
1359 +    sendto_realops_flags(UMODE_ALL, L_OPER,
1360 +                         "Lost connect{} block for %s", get_client_name(client_p, MASK_IP));
1361 +
1362 +    exit_client(client_p, &me, "Lost connect{} block");
1363 +    return;
1364 +  }
1365 +
1366 +  aconf = map_to_conf(conf);
1367 +
1368 +  /* jdc -- Check and send spasswd, not passwd. */
1369 +  if (!EmptyString(aconf->spasswd))
1370 +    sendto_one(client_p, "PASS %s TS %d %s",
1371 +               aconf->spasswd, TS_CURRENT, me.id);
1372 +
1373 +  send_capabilities(client_p, aconf,
1374 +                   (IsConfTopicBurst(aconf) ? CAP_TBURST|CAP_TB : 0));
1375 +
1376 +  sendto_one(client_p, "SERVER %s 1 :%s%s",
1377 +             me.name, ConfigServerHide.hidden ? "(H) " : "",
1378 +             me.info);
1379 +
1380 +  /* If we've been marked dead because a send failed, just exit
1381 +   * here now and save everyone the trouble of us ever existing.
1382 +   */
1383 +  if (IsDead(client_p))
1384 +  {
1385 +      sendto_realops_flags(UMODE_ALL, L_ADMIN,
1386 +                           "%s[%s] went dead during handshake",
1387 +                           client_p->name,
1388 +                           client_p->host);
1389 +      sendto_realops_flags(UMODE_ALL, L_OPER,
1390 +                           "%s went dead during handshake", client_p->name);
1391 +      return;
1392 +  }
1393 +
1394 +  /* don't move to serv_list yet -- we haven't sent a burst! */
1395 +  /* If we get here, we're ok, so lets start reading some data */
1396 +  comm_setselect(&client_p->localClient->fd, COMM_SELECT_READ, read_packet, client_p, 0);
1397 + }
1398 +
1399 + static void
1400 + ssl_server_handshake(fde_t *fd, struct Client *client_p)
1401 + {
1402 +  int ret;
1403 +  int err;
1404 +
1405 +  ret = SSL_connect(client_p->localClient->fd.ssl);
1406 +
1407 +  if (ret <= 0)
1408 +  {
1409 +    switch ((err = SSL_get_error(client_p->localClient->fd.ssl, ret)))
1410 +    {
1411 +      case SSL_ERROR_WANT_WRITE:
1412 +        comm_setselect(&client_p->localClient->fd, COMM_SELECT_WRITE,
1413 +                       (PF *)ssl_server_handshake, client_p, 0);
1414 +        return;
1415 +      case SSL_ERROR_WANT_READ:
1416 +        comm_setselect(&client_p->localClient->fd, COMM_SELECT_READ,
1417 +                       (PF *)ssl_server_handshake, client_p, 0);
1418 +        return;
1419 +      default:
1420 +      {
1421 +        const char *sslerr = ERR_error_string(ERR_get_error(), NULL);
1422 +        sendto_realops_flags(UMODE_ALL, L_ALL,
1423 +                             "Error connecting to %s: %s", client_p->name,
1424 +                             sslerr ? sslerr : "unknown SSL error");
1425 +        exit_client(client_p, client_p, "Error during SSL handshake");
1426 +        return;
1427 +      }
1428 +    }
1429 +  }
1430 +
1431 +  finish_ssl_server_handshake(client_p);
1432 + }
1433 +
1434 + static void
1435 + ssl_connect_init(struct Client *client_p, struct AccessItem *aconf, fde_t *fd)
1436 + {
1437 +  if ((client_p->localClient->fd.ssl = SSL_new(ServerInfo.client_ctx)) == NULL)
1438 +  {
1439 +    ilog(LOG_TYPE_IRCD, "SSL_new() ERROR! -- %s",
1440 +         ERR_error_string(ERR_get_error(), NULL));
1441 +    SetDead(client_p);
1442 +    exit_client(client_p, client_p, "SSL_new failed");
1443 +    return;
1444 +  }
1445 +
1446 +  SSL_set_fd(fd->ssl, fd->fd);
1447 +
1448 +  if (!EmptyString(aconf->cipher_list))
1449 +    SSL_set_cipher_list(client_p->localClient->fd.ssl, aconf->cipher_list);
1450 +
1451 +  ssl_server_handshake(NULL, client_p);
1452 + }
1453 + #endif
1454 +
1455   /* serv_connect_callback() - complete a server connection.
1456   *
1457   * This routine is called after the server connection attempt has
# Line 1398 | Line 1515 | serv_connect_callback(fde_t *fd, int sta
1515      return;
1516    }
1517  
1518 <  aconf = (struct AccessItem *)map_to_conf(conf);
1518 >  aconf = map_to_conf(conf);
1519    /* Next, send the initial handshake */
1520    SetHandshake(client_p);
1521  
1522   #ifdef HAVE_LIBCRYPTO
1523 <  /* TBD: initialization */
1523 >  if (IsConfSSL(aconf))
1524 >  {
1525 >    ssl_connect_init(client_p, aconf, fd);
1526 >    return;
1527 >  }
1528   #endif
1529  
1530    /* jdc -- Check and send spasswd, not passwd. */
1531    if (!EmptyString(aconf->spasswd))
1411      /* Send TS 6 form only if id */
1532      sendto_one(client_p, "PASS %s TS %d %s",
1533                 aconf->spasswd, TS_CURRENT, me.id);
1534  
1415  /* Pass my info to the new server
1416   *
1417   * Pass on ZIP if supported
1418   * Pass on TB if supported.
1419   * - Dianora
1420   */
1535    send_capabilities(client_p, aconf,
1536                     (IsConfTopicBurst(aconf) ? CAP_TBURST|CAP_TB : 0));
1537  

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)