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/trunk/src/s_serv.c (file contents):
Revision 1972 by michael, Wed May 8 18:41:37 2013 UTC vs.
Revision 2309 by michael, Wed Jun 19 20:48:02 2013 UTC

# Line 54 | Line 54
54  
55   #define MIN_CONN_FREQ 300
56  
57 + dlink_list flatten_links;
58   static dlink_list cap_list = { NULL, NULL, 0 };
59   static void server_burst(struct Client *);
60   static void burst_all(struct Client *);
# Line 72 | Line 73 | static void burst_members(struct Client
73   *                but in no particular order.
74   */
75   void
76 < write_links_file(void* notused)
76 > write_links_file(void *notused)
77   {
78 <  MessageFileLine *next_mptr = NULL;
79 <  MessageFileLine *mptr = NULL;
80 <  MessageFileLine *currentMessageLine = NULL;
80 <  MessageFileLine *newMessageLine = NULL;
81 <  MessageFile *MessageFileptr = &ConfigFileEntry.linksfile;
82 <  FILE *file;
83 <  char buff[512];
84 <  dlink_node *ptr;
78 >  FILE *file = NULL;
79 >  dlink_node *ptr = NULL, *ptr_next = NULL;
80 >  char buff[IRCD_BUFSIZE] = { '\0' };
81  
82 <  if ((file = fopen(MessageFileptr->fileName, "w")) == NULL)
82 >  if ((file = fopen(LIPATH, "w")) == NULL)
83      return;
84  
85 <  for (mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr)
85 >  DLINK_FOREACH_SAFE(ptr, ptr_next, flatten_links.head)
86    {
87 <    next_mptr = mptr->next;
88 <    MyFree(mptr);
87 >    dlinkDelete(ptr, &flatten_links);
88 >    MyFree(ptr->data);
89 >    free_dlink_node(ptr);
90    }
91  
95  MessageFileptr->contentsOfFile = NULL;
96
92    DLINK_FOREACH(ptr, global_serv_list.head)
93    {
94      const struct Client *target_p = ptr->data;
95  
96 <    /* skip ourselves, we send ourselves in /links */
97 <    if (IsMe(target_p))
98 <      continue;
99 <
100 <    /* skip hidden servers */
106 <    if (IsHidden(target_p))
96 >    /*
97 >     * Skip hidden servers, aswell as ourselves, since we already send
98 >     * ourselves in /links
99 >     */
100 >    if (IsHidden(target_p) || IsMe(target_p))
101        continue;
102  
103      if (HasFlag(target_p, FLAGS_SERVICE) && ConfigServerHide.hide_services)
104        continue;
105  
112    newMessageLine = MyMalloc(sizeof(MessageFileLine));
113
106      /*
107       * Attempt to format the file in such a way it follows the usual links output
108       * ie  "servername uplink :hops info"
109       * Mostly for aesthetic reasons - makes it look pretty in mIRC ;)
110       * - madmax
111       */
112 <    snprintf(newMessageLine->line, sizeof(newMessageLine->line), "%s %s :1 %s",
113 <             target_p->name, me.name, target_p->info);
112 >    snprintf(buff, sizeof(buff), "%s %s :1 %s",   target_p->name,
113 >             me.name, target_p->info);
114 >    dlinkAddTail(xstrdup(buff), make_dlink_node(), &flatten_links);
115 >    snprintf(buff, sizeof(buff), "%s %s :1 %s\n", target_p->name,
116 >             me.name, target_p->info);
117  
123    if (MessageFileptr->contentsOfFile)
124    {
125      if (currentMessageLine)
126        currentMessageLine->next = newMessageLine;
127      currentMessageLine = newMessageLine;
128    }
129    else
130    {
131      MessageFileptr->contentsOfFile = newMessageLine;
132      currentMessageLine = newMessageLine;
133    }
134
135    snprintf(buff, sizeof(buff), "%s %s :1 %s\n",
136             target_p->name, me.name, target_p->info);
118      fputs(buff, file);
119    }
120  
121    fclose(file);
122   }
123  
124 + void
125 + read_links_file(void)
126 + {
127 +  FILE *file = NULL;
128 +  char *p = NULL;
129 +  char buff[IRCD_BUFSIZE] = { '\0' };
130 +
131 +  if ((file = fopen(LIPATH, "r")) == NULL)
132 +    return;
133 +
134 +  while (fgets(buff, sizeof(buff), file))
135 +  {
136 +    if ((p = strchr(buff, '\n')) != NULL)
137 +      *p = '\0';
138 +
139 +    dlinkAddTail(xstrdup(buff), make_dlink_node(), &flatten_links);
140 +  }
141 +
142 +  fclose(file);
143 + }
144 +
145   /* hunt_server()
146   *      Do the basic thing in delivering the message (command)
147   *      across the relays to the specific server (server) for
# Line 192 | Line 194 | hunt_server(struct Client *client_p, str
194      if (target_p->from == source_p->from && !MyConnect(target_p))
195        target_p = NULL;
196  
195  collapse(parv[server]);
197    wilds = has_wildcards(parv[server]);
198  
199    /* Again, if there are no wild cards involved in the server
# Line 206 | Line 207 | hunt_server(struct Client *client_p, str
207        {
208          sendto_one(source_p, form_str(ERR_NOSUCHSERVER),
209                     me.name, source_p->name, parv[server]);
210 <        return(HUNTED_NOSUCH);
210 >        return HUNTED_NOSUCH;
211        }
212      }
213      else
# Line 252 | Line 253 | hunt_server(struct Client *client_p, str
253      sendto_one(target_p, command, parv[0],
254                 parv[1], parv[2], parv[3], parv[4],
255                 parv[5], parv[6], parv[7], parv[8]);
256 <    return(HUNTED_PASS);
256 >    return HUNTED_PASS;
257    }
258  
259    sendto_one(source_p, form_str(ERR_NOSUCHSERVER),
260               me.name, source_p->name, parv[server]);
261 <  return(HUNTED_NOSUCH);
261 >  return HUNTED_NOSUCH;
262   }
263  
264   /* try_connections()
# Line 308 | Line 309 | try_connections(void *unused)
309      {
310        confrq = conf->class->con_freq;
311        if (confrq < MIN_CONN_FREQ)
312 <        confrq = MIN_CONN_FREQ;
312 >        confrq = MIN_CONN_FREQ;
313      }
314  
315      conf->until = CurrentTime + confrq;
# Line 406 | Line 407 | check_server(const char *name, struct Cl
407        if (!match_conf_password(client_p->localClient->passwd, conf))
408          return -2;
409  
410 +      if (!EmptyString(conf->certfp))
411 +        if (EmptyString(client_p->certfp) || strcasecmp(client_p->certfp, conf->certfp))
412 +          return -4;
413 +
414        server_conf = conf;
415      }
416    }
417  
418    if (server_conf == NULL)
419 <    return(error);
419 >    return error;
420  
421    attach_conf(client_p, server_conf);
422  
# Line 441 | Line 446 | check_server(const char *name, struct Cl
446      }
447    }
448  
449 <  return(0);
449 >  return 0;
450   }
451  
452   /* add_capability()
# Line 487 | Line 492 | delete_capability(const char *capab_name
492      {
493        if (irccmp(cap->name, capab_name) == 0)
494        {
495 <        default_server_capabs &= ~(cap->cap);
496 <        dlinkDelete(ptr, &cap_list);
497 <        MyFree(cap->name);
498 <        cap->name = NULL;
494 <        MyFree(cap);
495 >        default_server_capabs &= ~(cap->cap);
496 >        dlinkDelete(ptr, &cap_list);
497 >        MyFree(cap->name);
498 >        MyFree(cap);
499        }
500      }
501    }
# Line 616 | Line 620 | sendnick_TS(struct Client *client_p, str
620                   target_p->servptr->name, target_p->info);
621    }
622  
623 +  if (!EmptyString(target_p->certfp))
624 +    sendto_one(client_p, ":%s CERTFP %s",
625 +               ID_or_name(target_p, client_p), target_p->certfp);
626 +
627    if (target_p->away[0])
628      sendto_one(client_p, ":%s AWAY :%s", ID_or_name(target_p, client_p),
629                 target_p->away);
# Line 630 | Line 638 | sendnick_TS(struct Client *client_p, str
638   * side effects - build up string representing capabilities of server listed
639   */
640   const char *
641 < show_capabilities(struct Client *target_p)
641 > show_capabilities(const struct Client *target_p)
642   {
643 <  static char msgbuf[IRCD_BUFSIZE];
644 <  char *t = msgbuf;
637 <  dlink_node *ptr;
643 >  static char msgbuf[IRCD_BUFSIZE] = "";
644 >  const dlink_node *ptr = NULL;
645  
646 <  t += sprintf(msgbuf, "TS ");
646 >  strlcpy(msgbuf, "TS", sizeof(msgbuf));
647  
648    DLINK_FOREACH(ptr, cap_list.head)
649    {
650      const struct Capability *cap = ptr->data;
651  
652 <    if (IsCapable(target_p, cap->cap))
653 <      t += sprintf(t, "%s ", cap->name);
652 >    if (!IsCapable(target_p, cap->cap))
653 >      continue;
654 >
655 >    strlcat(msgbuf,       " ", sizeof(msgbuf));
656 >    strlcat(msgbuf, cap->name, sizeof(msgbuf));
657    }
658  
649  *(t - 1) = '\0';
659    return msgbuf;
660   }
661  
# Line 725 | Line 734 | server_estab(struct Client *client_p)
734  
735    if (IsUnknown(client_p))
736    {
737 <    /* jdc -- 1.  Use EmptyString(), not [0] index reference.
729 <     *        2.  Check conf->spasswd, not conf->passwd.
730 <     */
731 <    if (!EmptyString(conf->spasswd))
732 <      sendto_one(client_p, "PASS %s TS %d %s",
733 <                 conf->spasswd, TS_CURRENT, me.id);
737 >    sendto_one(client_p, "PASS %s TS %d %s", conf->spasswd, TS_CURRENT, me.id);
738  
739      send_capabilities(client_p, 0);
740  
# Line 955 | Line 959 | burst_all(struct Client *client_p)
959        send_channel_modes(client_p, chptr);
960  
961        if (IsCapable(client_p, CAP_TBURST))
962 <        send_tb(client_p, chptr);
962 >        send_tb(client_p, chptr);
963      }
964    }
965  
# Line 1099 | Line 1103 | serv_connect(struct MaskItem *conf, stru
1103    if ((client_p = hash_find_server(conf->name)) != NULL)
1104    {
1105      sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
1106 <                         "Server %s already present from %s",
1107 <                         conf->name, get_client_name(client_p, SHOW_IP));
1106 >                         "Server %s already present from %s",
1107 >                         conf->name, get_client_name(client_p, SHOW_IP));
1108      sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
1109 <                         "Server %s already present from %s",
1110 <                         conf->name, get_client_name(client_p, MASK_IP));
1109 >                         "Server %s already present from %s",
1110 >                         conf->name, get_client_name(client_p, MASK_IP));
1111      if (by && IsClient(by) && !MyClient(by))
1112        sendto_one(by, ":%s NOTICE %s :Server %s already present from %s",
1113 <                 me.name, by->name, conf->name,
1114 <                 get_client_name(client_p, MASK_IP));
1115 <    return (0);
1113 >                 me.name, by->name, conf->name,
1114 >                 get_client_name(client_p, MASK_IP));
1115 >    return 0;
1116    }
1117      
1118    /* Create a local client */
# Line 1126 | Line 1130 | serv_connect(struct MaskItem *conf, stru
1130                  SOCK_STREAM, 0, NULL) < 0)
1131    {
1132      /* Eek, failure to create the socket */
1133 <    report_error(L_ALL,
1134 <                 "opening stream socket to %s: %s", conf->name, errno);
1133 >    report_error(L_ALL, "opening stream socket to %s: %s",
1134 >                 conf->name, errno);
1135      SetDead(client_p);
1136      exit_client(client_p, &me, "Connection failed");
1137 <    return (0);
1137 >    return 0;
1138    }
1139  
1140    /* servernames are always guaranteed under HOSTLEN chars */
# Line 1142 | Line 1146 | serv_connect(struct MaskItem *conf, stru
1146    if (!attach_connect_block(client_p, conf->name, conf->host))
1147    {
1148      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1149 <                         "Host %s is not enabled for connecting: no connect{} block",
1150 <                         conf->name);
1149 >                         "Host %s is not enabled for connecting: no connect{} block",
1150 >                         conf->name);
1151      if (by && IsClient(by) && !MyClient(by))  
1152        sendto_one(by, ":%s NOTICE %s :Connect to host %s failed.",
1153 <                 me.name, by->name, client_p->name);
1153 >                 me.name, by->name, client_p->name);
1154      SetDead(client_p);
1155      exit_client(client_p, client_p, "Connection failed");
1156 <    return (0);
1156 >    return 0;
1157    }
1158  
1159    /* at this point we have a connection in progress and C/N lines
# Line 1185 | Line 1189 | serv_connect(struct MaskItem *conf, stru
1189          ipn.ss.ss_family = AF_INET;
1190          ipn.ss_port = 0;
1191          memcpy(&ipn, &conf->bind, sizeof(struct irc_ssaddr));
1192 <        comm_connect_tcp(&client_p->localClient->fd, conf->host, conf->port,
1193 <                         (struct sockaddr *)&ipn, ipn.ss_len,
1194 <                         serv_connect_callback, client_p, conf->aftype,
1195 <                         CONNECTTIMEOUT);
1192 >        comm_connect_tcp(&client_p->localClient->fd, conf->host, conf->port,
1193 >                         (struct sockaddr *)&ipn, ipn.ss_len,
1194 >                         serv_connect_callback, client_p, conf->aftype,
1195 >                         CONNECTTIMEOUT);
1196        }
1197        else if (ServerInfo.specific_ipv4_vhost)
1198        {
# Line 1200 | Line 1204 | serv_connect(struct MaskItem *conf, stru
1204          comm_connect_tcp(&client_p->localClient->fd, conf->host, conf->port,
1205                           (struct sockaddr *)&ipn, ipn.ss_len,
1206                           serv_connect_callback, client_p, conf->aftype,
1207 <                         CONNECTTIMEOUT);
1207 >                         CONNECTTIMEOUT);
1208        }
1209        else
1210          comm_connect_tcp(&client_p->localClient->fd, conf->host, conf->port,
# Line 1210 | Line 1214 | serv_connect(struct MaskItem *conf, stru
1214   #ifdef IPV6
1215      case AF_INET6:
1216        {
1217 <        struct irc_ssaddr ipn;
1218 <        struct sockaddr_in6 *v6;
1219 <        struct sockaddr_in6 *v6conf;
1220 <
1221 <        memset(&ipn, 0, sizeof(struct irc_ssaddr));
1222 <        v6conf = (struct sockaddr_in6 *)&conf->bind;
1223 <        v6 = (struct sockaddr_in6 *)&ipn;
1224 <
1225 <        if (memcmp(&v6conf->sin6_addr, &v6->sin6_addr,
1222 <                   sizeof(struct in6_addr)) != 0)
1223 <        {
1224 <          memcpy(&ipn, &conf->bind, sizeof(struct irc_ssaddr));
1225 <          ipn.ss.ss_family = AF_INET6;
1226 <          ipn.ss_port = 0;
1227 <          comm_connect_tcp(&client_p->localClient->fd,
1228 <                           conf->host, conf->port,
1229 <                           (struct sockaddr *)&ipn, ipn.ss_len,
1230 <                           serv_connect_callback, client_p,
1231 <                           conf->aftype, CONNECTTIMEOUT);
1232 <        }
1233 <        else if (ServerInfo.specific_ipv6_vhost)
1217 >        struct irc_ssaddr ipn;
1218 >        struct sockaddr_in6 *v6;
1219 >        struct sockaddr_in6 *v6conf;
1220 >
1221 >        memset(&ipn, 0, sizeof(struct irc_ssaddr));
1222 >        v6conf = (struct sockaddr_in6 *)&conf->bind;
1223 >        v6 = (struct sockaddr_in6 *)&ipn;
1224 >
1225 >        if (memcmp(&v6conf->sin6_addr, &v6->sin6_addr, sizeof(struct in6_addr)) != 0)
1226          {
1227 <          memcpy(&ipn, &ServerInfo.ip6, sizeof(struct irc_ssaddr));
1228 <          ipn.ss.ss_family = AF_INET6;
1229 <          ipn.ss_port = 0;
1230 <          comm_connect_tcp(&client_p->localClient->fd,
1231 <                           conf->host, conf->port,
1232 <                           (struct sockaddr *)&ipn, ipn.ss_len,
1233 <                           serv_connect_callback, client_p,
1234 <                           conf->aftype, CONNECTTIMEOUT);
1235 <        }
1236 <        else
1237 <          comm_connect_tcp(&client_p->localClient->fd,
1238 <                           conf->host, conf->port,
1239 <                           NULL, 0, serv_connect_callback, client_p,
1240 <                           conf->aftype, CONNECTTIMEOUT);
1227 >          memcpy(&ipn, &conf->bind, sizeof(struct irc_ssaddr));
1228 >          ipn.ss.ss_family = AF_INET6;
1229 >          ipn.ss_port = 0;
1230 >          comm_connect_tcp(&client_p->localClient->fd,
1231 >                           conf->host, conf->port,
1232 >                           (struct sockaddr *)&ipn, ipn.ss_len,
1233 >                           serv_connect_callback, client_p,
1234 >                           conf->aftype, CONNECTTIMEOUT);
1235 >        }
1236 >        else if (ServerInfo.specific_ipv6_vhost)
1237 >        {
1238 >          memcpy(&ipn, &ServerInfo.ip6, sizeof(struct irc_ssaddr));
1239 >          ipn.ss.ss_family = AF_INET6;
1240 >          ipn.ss_port = 0;
1241 >          comm_connect_tcp(&client_p->localClient->fd,
1242 >                           conf->host, conf->port,
1243 >                           (struct sockaddr *)&ipn, ipn.ss_len,
1244 >                           serv_connect_callback, client_p,
1245 >                           conf->aftype, CONNECTTIMEOUT);
1246 >        }
1247 >        else
1248 >          comm_connect_tcp(&client_p->localClient->fd,
1249 >                           conf->host, conf->port,
1250 >                           NULL, 0, serv_connect_callback, client_p,
1251 >                           conf->aftype, CONNECTTIMEOUT);
1252        }
1253   #endif
1254    }
1255 <  return (1);
1255 >  return 1;
1256   }
1257  
1258   #ifdef HAVE_LIBCRYPTO
# Line 1271 | Line 1274 | finish_ssl_server_handshake(struct Clien
1274      return;
1275    }
1276  
1277 <  /* jdc -- Check and send spasswd, not passwd. */
1275 <  if (!EmptyString(conf->spasswd))
1276 <    sendto_one(client_p, "PASS %s TS %d %s",
1277 <               conf->spasswd, TS_CURRENT, me.id);
1277 >  sendto_one(client_p, "PASS %s TS %d %s", conf->spasswd, TS_CURRENT, me.id);
1278  
1279    send_capabilities(client_p, 0);
1280  
# Line 1390 | Line 1390 | serv_connect_callback(fde_t *fd, int sta
1390                              client_p->name, comm_errstr(status));
1391       else
1392         sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
1393 <                            "Error connecting to %s[%s]: %s", client_p->name,
1394 <                            client_p->host, comm_errstr(status));
1393 >                            "Error connecting to %s[%s]: %s", client_p->name,
1394 >                            client_p->host, comm_errstr(status));
1395  
1396       sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
1397 <                          "Error connecting to %s: %s",
1398 <                          client_p->name, comm_errstr(status));
1397 >                          "Error connecting to %s: %s",
1398 >                          client_p->name, comm_errstr(status));
1399  
1400       /* If a fd goes bad, call dead_link() the socket is no
1401        * longer valid for reading or writing.
# Line 1407 | Line 1407 | serv_connect_callback(fde_t *fd, int sta
1407    /* COMM_OK, so continue the connection procedure */
1408    /* Get the C/N lines */
1409    conf = find_conf_name(&client_p->localClient->confs,
1410 <                        client_p->name, CONF_SERVER);
1410 >                        client_p->name, CONF_SERVER);
1411    if (conf == NULL)
1412    {
1413      sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
1414 <                         "Lost connect{} block for %s", get_client_name(client_p, HIDE_IP));
1414 >                         "Lost connect{} block for %s", get_client_name(client_p, HIDE_IP));
1415      sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
1416 <                         "Lost connect{} block for %s", get_client_name(client_p, MASK_IP));
1416 >                         "Lost connect{} block for %s", get_client_name(client_p, MASK_IP));
1417  
1418      exit_client(client_p, &me, "Lost connect{} block");
1419      return;
# Line 1430 | Line 1430 | serv_connect_callback(fde_t *fd, int sta
1430    }
1431   #endif
1432  
1433 <  /* jdc -- Check and send spasswd, not passwd. */
1434 <  if (!EmptyString(conf->spasswd))
1435 <    sendto_one(client_p, "PASS %s TS %d %s",
1436 <               conf->spasswd, TS_CURRENT, me.id);
1433 >  sendto_one(client_p, "PASS %s TS %d %s", conf->spasswd, TS_CURRENT, me.id);
1434  
1435    send_capabilities(client_p, 0);
1436  
1437 <  sendto_one(client_p, "SERVER %s 1 :%s%s",
1438 <             me.name, ConfigServerHide.hidden ? "(H) " : "",
1442 <             me.info);
1437 >  sendto_one(client_p, "SERVER %s 1 :%s%s", me.name,
1438 >             ConfigServerHide.hidden ? "(H) " : "", me.info);
1439  
1440    /* If we've been marked dead because a send failed, just exit
1441     * here now and save everyone the trouble of us ever existing.
# Line 1447 | Line 1443 | serv_connect_callback(fde_t *fd, int sta
1443    if (IsDead(client_p))
1444    {
1445        sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
1446 <                           "%s[%s] went dead during handshake",
1446 >                           "%s[%s] went dead during handshake",
1447                             client_p->name,
1448 <                           client_p->host);
1448 >                           client_p->host);
1449        sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
1450 <                           "%s went dead during handshake", client_p->name);
1450 >                           "%s went dead during handshake", client_p->name);
1451        return;
1452    }
1453  

Diff Legend

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