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

Comparing ircd-hybrid/trunk/src/client.c (file contents):
Revision 6963 by michael, Fri Dec 18 19:34:18 2015 UTC vs.
Revision 8664 by michael, Thu Nov 22 14:26:32 2018 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 1997-2015 ircd-hybrid development team
4 > *  Copyright (c) 1997-2018 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 27 | Line 27
27   #include "stdinc.h"
28   #include "list.h"
29   #include "client.h"
30 + #include "client_svstag.h"
31   #include "event.h"
32   #include "hash.h"
33   #include "irc_string.h"
# Line 35 | Line 36
36   #include "auth.h"
37   #include "s_bsd.h"
38   #include "conf.h"
39 + #include "conf_gecos.h"
40   #include "log.h"
41   #include "misc.h"
42   #include "server.h"
# Line 42 | Line 44
44   #include "whowas.h"
45   #include "user.h"
46   #include "memory.h"
45 #include "mempool.h"
47   #include "hostmask.h"
48   #include "listener.h"
48 #include "userhost.h"
49   #include "watch.h"
50   #include "rng_mt.h"
51   #include "parse.h"
# Line 60 | Line 60 | dlink_list global_client_list;
60   dlink_list global_server_list;
61   dlink_list oper_list;
62  
63 static mp_pool_t *client_pool, *connection_pool;
63   static dlink_list dead_list, abort_list;
64   static dlink_node *eac_next;  /* next aborted client to exit */
65  
66  
67   /*
68 < * make_client - create a new Client struct and set it to initial state.
68 > * client_make - create a new Client struct and set it to initial state.
69   *
70   *      from == NULL,   create local client (a client connected
71   *                      to a socket).
# Line 81 | Line 80 | static dlink_node *eac_next;  /* next ab
80   *                      'from'). ('from' is a local client!!).
81   */
82   struct Client *
83 < make_client(struct Client *from)
83 > client_make(struct Client *from)
84   {
85 <  struct Client *const client_p = mp_pool_get(client_pool);
85 >  struct Client *client_p = xcalloc(sizeof(*client_p));
86  
87 <  if (!from)
87 >  if (from)
88 >    client_p->from = from;
89 >  else
90    {
91      client_p->from = client_p;  /* 'from' of local client is self! */
92 <    client_p->connection = mp_pool_get(connection_pool);
92 >    client_p->connection = xcalloc(sizeof(*client_p->connection));
93      client_p->connection->since = CurrentTime;
94      client_p->connection->lasttime = CurrentTime;
95      client_p->connection->firsttime = CurrentTime;
# Line 97 | Line 98 | make_client(struct Client *from)
98      /* as good a place as any... */
99      dlinkAdd(client_p, &client_p->connection->lclient_node, &unknown_list);
100    }
100  else
101    client_p->from = from;
101  
102    client_p->idhnext = client_p;
103    client_p->hnext = client_p;
# Line 110 | Line 109 | make_client(struct Client *from)
109   }
110  
111   /*
112 < * free_client
112 > * client_free
113   *
114   * inputs       - pointer to client
115   * output       - NONE
116   * side effects - client pointed to has its memory freed
117   */
118   static void
119 < free_client(struct Client *client_p)
119 > client_free(struct Client *client_p)
120   {
121 +  assert(!IsMe(client_p));
122    assert(client_p != &me);
123    assert(client_p->hnext == client_p);
124    assert(client_p->idhnext == client_p);
125 <  assert(client_p->channel.head == NULL);
125 >
126 >  assert(client_p->node.prev == NULL);
127 >  assert(client_p->node.next == NULL);
128 >
129 >  assert(client_p->lnode.prev == NULL);
130 >  assert(client_p->lnode.next == NULL);
131 >
132 >  assert(dlink_list_length(&client_p->whowas_list) == 0);
133 >  assert(client_p->whowas_list.head == NULL);
134 >  assert(client_p->whowas_list.tail == NULL);
135 >
136    assert(dlink_list_length(&client_p->channel) == 0);
137 <  assert(dlink_list_length(&client_p->whowas) == 0);
137 >  assert(client_p->channel.head == NULL);
138 >  assert(client_p->channel.tail == NULL);
139 >
140    assert(dlink_list_length(&client_p->svstags) == 0);
141 +  assert(client_p->svstags.head == NULL);
142 +  assert(client_p->svstags.tail == NULL);
143 +
144  
145 <  MyFree(client_p->serv);
146 <  MyFree(client_p->certfp);
145 >  xfree(client_p->serv);
146 >  xfree(client_p->certfp);
147  
148    if (MyConnect(client_p))
149    {
150 <    assert(client_p->connection->invited.head == NULL);
151 <    assert(dlink_list_length(&client_p->connection->invited) == 0);
150 >    assert(client_p->connection->lclient_node.prev == NULL);
151 >    assert(client_p->connection->lclient_node.next == NULL);
152 >
153 >    assert(client_p->connection->list_task == NULL);
154 >    assert(client_p->connection->auth == NULL);
155 >
156 >    assert(dlink_list_length(&client_p->connection->acceptlist) == 0);
157 >    assert(client_p->connection->acceptlist.head == NULL);
158 >    assert(client_p->connection->acceptlist.tail == NULL);
159 >
160 >
161      assert(dlink_list_length(&client_p->connection->watches) == 0);
162 +    assert(client_p->connection->watches.head == NULL);
163 +    assert(client_p->connection->watches.tail == NULL);
164 +
165 +    assert(dlink_list_length(&client_p->connection->confs) == 0);
166 +    assert(client_p->connection->confs.head == NULL);
167 +    assert(client_p->connection->confs.tail == NULL);
168 +
169 +    assert(dlink_list_length(&client_p->connection->invited) == 0);
170 +    assert(client_p->connection->invited.head == NULL);
171 +    assert(client_p->connection->invited.tail == NULL);
172 +
173 +    assert(client_p->connection->fd == NULL);
174 +
175      assert(HasFlag(client_p, FLAGS_CLOSING) && IsDead(client_p));
176  
177      /*
# Line 149 | Line 186 | free_client(struct Client *client_p)
186      dbuf_clear(&client_p->connection->buf_recvq);
187      dbuf_clear(&client_p->connection->buf_sendq);
188  
189 <    mp_pool_release(client_p->connection);
189 >    xfree(client_p->connection);
190 >    client_p->connection = NULL;
191    }
192  
193 <  mp_pool_release(client_p);
156 < }
157 <
158 < void
159 < client_attach_svstag(struct Client *client_p, unsigned int numeric,
160 <                     const char *umodes, const char *const tag)
161 < {
162 <  struct ServicesTag *svstag = NULL;
163 <  const struct user_modes *tab = NULL;
164 <
165 <  if (numeric >= ERR_LAST_ERR_MSG || *umodes != '+')
166 <    return;
167 <
168 <  svstag = MyCalloc(sizeof(*svstag));
169 <  svstag->numeric = numeric;
170 <  svstag->tag = xstrdup(tag);
171 <
172 <  for (const char *m = umodes + 1; *m; ++m)
173 <    if ((tab = umode_map[(unsigned char)*m]))
174 <      svstag->umodes |= tab->flag;
175 <
176 <  if (numeric != RPL_WHOISOPERATOR)
177 <    dlinkAddTail(svstag, &svstag->node, &client_p->svstags);
178 <  else
179 <    dlinkAdd(svstag, &svstag->node, &client_p->svstags);
180 < }
181 <
182 < void
183 < client_clear_svstags(struct Client *client_p)
184 < {
185 <  dlink_node *node = NULL, *node_next = NULL;
186 <
187 <  DLINK_FOREACH_SAFE(node, node_next, client_p->svstags.head)
188 <  {
189 <    struct ServicesTag *svstag = node->data;
190 <
191 <    dlinkDelete(&svstag->node, &client_p->svstags);
192 <    MyFree(svstag->tag);
193 <    MyFree(svstag);
194 <  }
193 >  xfree(client_p);
194   }
195  
196   /* check_pings_list()
# Line 204 | Line 203 | static void
203   check_pings_list(dlink_list *list)
204   {
205    char buf[32] = "";  /* 32 = sizeof("Ping timeout: 999999999 seconds") */
206 <  int ping = 0;      /* ping time value from client */
207 <  dlink_node *node = NULL, *node_next = NULL;
206 >  unsigned int ping = 0;      /* ping time value from client */
207 >  dlink_node *node, *node_next;
208  
209    DLINK_FOREACH_SAFE(node, node_next, list->head)
210    {
211      struct Client *client_p = node->data;
212  
213      if (IsDead(client_p))
214 <      continue;  /* Ignore it, its been exited already */
214 >      continue;  /* Ignore it, it's been exited already */
215  
216      if (IsClient(client_p) || IsServer(client_p))
217        ping = get_client_ping(&client_p->connection->confs);
# Line 244 | Line 243 | check_pings_list(dlink_list *list)
243            {
244              sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
245                                   "No response from %s, closing link",
246 <                                 get_client_name(client_p, SHOW_IP));
246 >                                 client_get_name(client_p, SHOW_IP));
247              sendto_realops_flags(UMODE_SERVNOTICE, L_OPER, SEND_NOTICE,
248                                   "No response from %s, closing link",
249 <                                 get_client_name(client_p, MASK_IP));
249 >                                 client_get_name(client_p, MASK_IP));
250              ilog(LOG_TYPE_IRCD, "No response from %s, closing link",
251 <                 get_client_name(client_p, SHOW_IP));
251 >                 client_get_name(client_p, SHOW_IP));
252            }
253  
254            snprintf(buf, sizeof(buf), "Ping timeout: %ji seconds",
# Line 270 | Line 269 | check_pings_list(dlink_list *list)
269   static void
270   check_unknowns_list(void)
271   {
272 <  dlink_node *node = NULL, *node_next = NULL;
272 >  dlink_node *node, *node_next;
273  
274    DLINK_FOREACH_SAFE(node, node_next, unknown_list.head)
275    {
# Line 290 | Line 289 | check_unknowns_list(void)
289   * kill off stuff that should die
290   *
291   * inputs       - NOT USED (from event)
293 * output       - next time_t when check_pings() should be called again
292   * side effects -
293   *
294   *
# Line 329 | Line 327 | check_pings(void *unused)
327   void
328   check_conf_klines(void)
329   {
332  struct MaskItem *conf = NULL;
330    dlink_node *node = NULL, *node_next = NULL;
331 +  const void *ptr;
332  
333    DLINK_FOREACH_SAFE(node, node_next, local_client_list.head)
334    {
# Line 340 | Line 338 | check_conf_klines(void)
338      if (IsDead(client_p))
339        continue;
340  
341 <    if ((conf = find_conf_by_address(NULL, &client_p->connection->ip, CONF_DLINE,
342 <                                     client_p->connection->aftype, NULL, NULL, 1)))
341 >    if ((ptr = find_conf_by_address(NULL, &client_p->ip, CONF_DLINE,
342 >                                    client_p->ip.ss.ss_family, NULL, NULL, 1)))
343      {
344 <      conf_try_ban(client_p, conf);
344 >      const struct MaskItem *conf = ptr;
345 >      conf_try_ban(client_p, CLIENT_BAN_DLINE, conf->reason);
346        continue;  /* and go examine next Client */
347      }
348  
349 <    if ((conf = find_conf_by_address(client_p->host, &client_p->connection->ip,
350 <                                     CONF_KLINE, client_p->connection->aftype,
351 <                                     client_p->username, NULL, 1)))
349 >    if ((ptr = find_conf_by_address(client_p->host, &client_p->ip,
350 >                                    CONF_KLINE, client_p->ip.ss.ss_family,
351 >                                    client_p->username, NULL, 1)))
352      {
353 <      conf_try_ban(client_p, conf);
353 >      const struct MaskItem *conf = ptr;
354 >      conf_try_ban(client_p, CLIENT_BAN_KLINE, conf->reason);
355        continue;  /* and go examine next Client */
356      }
357  
358 <    if ((conf = find_matching_name_conf(CONF_XLINE, client_p->info,
359 <                                        NULL, NULL, 0)))
358 >    if ((ptr = gecos_find(client_p->info, match)))
359      {
360 <      conf_try_ban(client_p, conf);
360 >      const struct GecosItem *conf = ptr;
361 >      conf_try_ban(client_p, CLIENT_BAN_XLINE, conf->reason);
362        continue;  /* and go examine next Client */
363      }
364    }
# Line 368 | Line 368 | check_conf_klines(void)
368    {
369      struct Client *client_p = node->data;
370  
371 <    if ((conf = find_conf_by_address(NULL, &client_p->connection->ip, CONF_DLINE,
372 <                                     client_p->connection->aftype, NULL, NULL, 1)))
371 >    if ((ptr = find_conf_by_address(NULL, &client_p->ip, CONF_DLINE,
372 >                                    client_p->ip.ss.ss_family, NULL, NULL, 1)))
373      {
374 <      conf_try_ban(client_p, conf);
374 >      const struct MaskItem *conf = ptr;
375 >      conf_try_ban(client_p, CLIENT_BAN_DLINE, conf->reason);
376        continue;  /* and go examine next Client */
377      }
378    }
# Line 386 | Line 387 | check_conf_klines(void)
387   * side effects - given client_p is banned
388   */
389   void
390 < conf_try_ban(struct Client *client_p, struct MaskItem *conf)
390 > conf_try_ban(struct Client *client_p, int type, const char *reason)
391   {
392    char ban_type = '?';
393  
394 <  switch (conf->type)
394 >  switch (type)
395    {
396 <    case CONF_KLINE:
396 >    case CLIENT_BAN_KLINE:
397        if (HasFlag(client_p, FLAGS_EXEMPTKLINE))
398        {
399          sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
400                               "KLINE over-ruled for %s, client is kline_exempt",
401 <                             get_client_name(client_p, HIDE_IP));
401 >                             client_get_name(client_p, HIDE_IP));
402          return;
403        }
404  
405        ban_type = 'K';
406        break;
407 <    case CONF_DLINE:
408 <      if (find_conf_by_address(NULL, &client_p->connection->ip, CONF_EXEMPT,
409 <                               client_p->connection->aftype, NULL, NULL, 1))
407 >    case CLIENT_BAN_DLINE:
408 >      if (find_conf_by_address(NULL, &client_p->ip, CONF_EXEMPT,
409 >                               client_p->ip.ss.ss_family, NULL, NULL, 1))
410          return;
411        ban_type = 'D';
412        break;
413 <    case CONF_XLINE:
413 >    case CLIENT_BAN_XLINE:
414        if (HasFlag(client_p, FLAGS_EXEMPTXLINE))
415        {
416          sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
417                               "XLINE over-ruled for %s, client is xline_exempt",
418 <                             get_client_name(client_p, HIDE_IP));
418 >                             client_get_name(client_p, HIDE_IP));
419          return;
420        }
421  
422        ban_type = 'X';
422      ++conf->count;
423        break;
424      default:
425        assert(0);
# Line 427 | Line 427 | conf_try_ban(struct Client *client_p, st
427    }
428  
429    sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE, "%c-line active for %s",
430 <                       ban_type, get_client_name(client_p, HIDE_IP));
430 >                       ban_type, client_get_name(client_p, HIDE_IP));
431  
432    if (IsClient(client_p))
433 <    sendto_one_numeric(client_p, &me, ERR_YOUREBANNEDCREEP, conf->reason);
433 >    sendto_one_numeric(client_p, &me, ERR_YOUREBANNEDCREEP, reason);
434  
435 <  exit_client(client_p, conf->reason);
436 < }
437 <
438 < /* update_client_exit_stats()
439 < *
440 < * input        - pointer to client
441 < * output       - NONE
442 < * side effects -
443 < */
444 < static void
445 < update_client_exit_stats(struct Client *client_p)
446 < {
447 <  if (IsClient(client_p))
448 <  {
449 <    assert(Count.total > 0);
450 <
451 <    --Count.total;
452 <    if (HasUMode(client_p, UMODE_OPER))
453 <      --Count.oper;
454 <    if (HasUMode(client_p, UMODE_INVISIBLE))
455 <      --Count.invisi;
456 <  }
457 <  else if (IsServer(client_p))
458 <    sendto_realops_flags(UMODE_EXTERNAL, L_ALL, SEND_NOTICE,
459 <                         "Server %s split from %s",
460 <                         client_p->name, client_p->servptr->name);
435 >  exit_client(client_p, reason);
436   }
437  
438   /* find_person()
# Line 467 | Line 442 | update_client_exit_stats(struct Client *
442   * side effects - find person by (nick)name
443   */
444   struct Client *
445 < find_person(const struct Client *const source_p, const char *name)
445 > find_person(const struct Client *source_p, const char *name)
446   {
447    struct Client *target_p = NULL;
448  
# Line 498 | Line 473 | find_chasing(struct Client *source_p, co
473    if (IsDigit(*name))
474      return NULL;
475  
476 <  target_p = whowas_get_history(name, (time_t)ConfigGeneral.kill_chase_time_limit);
477 <
503 <  if (!target_p)
504 <  {
476 >  target_p = whowas_get_history(name, ConfigGeneral.kill_chase_time_limit);
477 >  if (target_p == NULL)
478      sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, name);
506    return NULL;
507  }
479  
480    return target_p;
481   }
482  
483   /*
484 < * get_client_name -  Return the name of the client
484 > * client_get_name -  Return the name of the client
485   *    for various tracking and
486   *      admin purposes. The main purpose of this function is to
487   *      return the "socket host" name of the client, if that
# Line 528 | Line 499 | find_chasing(struct Client *source_p, co
499   *        to modify what it points!!!
500   */
501   const char *
502 < get_client_name(const struct Client *client_p, enum addr_mask_type type)
502 > client_get_name(const struct Client *client_p, enum addr_mask_type type)
503   {
504    static char buf[HOSTLEN * 2 + USERLEN + 4];  /* +4 for [,@,],\0 */
505  
# Line 537 | Line 508 | get_client_name(const struct Client *cli
508  
509    if (IsServer(client_p) || IsConnecting(client_p) || IsHandshake(client_p))
510    {
511 <    if (!irccmp(client_p->name, client_p->host))
511 >    if (irccmp(client_p->name, client_p->host) == 0)
512        return client_p->name;
513      else if (ConfigServerHide.hide_server_ips)
514        type = MASK_IP;
# Line 552 | Line 523 | get_client_name(const struct Client *cli
523                 client_p->username, client_p->sockhost);
524        break;
525      case MASK_IP:
526 <      if (client_p->connection->aftype == AF_INET)
526 >      if (client_p->ip.ss.ss_family == AF_INET)
527          snprintf(buf, sizeof(buf), "%s[%s@255.255.255.255]",
528                   client_p->name, client_p->username);
529        else
# Line 571 | Line 542 | get_client_name(const struct Client *cli
542   void
543   free_exited_clients(void)
544   {
545 <  dlink_node *node = NULL, *node_next = NULL;
545 >  dlink_node *node, *node_next;
546  
547    DLINK_FOREACH_SAFE(node, node_next, dead_list.head)
548    {
549 <    free_client(node->data);
549 >    client_free(node->data);
550      dlinkDelete(node, &dead_list);
551      free_dlink_node(node);
552    }
553   }
554  
555   /*
556 + * client_close_connection
557 + *        Close the physical connection. This function must make
558 + *        MyConnect(client_p) == FALSE, and set client_p->from == NULL.
559 + */
560 + static void
561 + client_close_connection(struct Client *client_p)
562 + {
563 +  assert(client_p);
564 +
565 +  if (!IsDead(client_p))
566 +  {
567 +    /* Attempt to flush any pending dbufs. Evil, but .. -- adrian */
568 +    /*
569 +     * There is still a chance that we might send data to this socket
570 +     * even if it is marked as blocked (COMM_SELECT_READ handler is called
571 +     * before COMM_SELECT_WRITE). Let's try, nothing to lose.. -adx
572 +     */
573 +    DelFlag(client_p, FLAGS_BLOCKED);
574 +    send_queued_write(client_p);
575 +  }
576 +
577 +  if (IsClient(client_p))
578 +  {
579 +    ++ServerStats.is_cl;
580 +    ServerStats.is_cbs += client_p->connection->send.bytes;
581 +    ServerStats.is_cbr += client_p->connection->recv.bytes;
582 +    ServerStats.is_cti += CurrentTime - client_p->connection->firsttime;
583 +  }
584 +  else if (IsServer(client_p))
585 +  {
586 +    dlink_node *node;
587 +
588 +    ++ServerStats.is_sv;
589 +    ServerStats.is_sbs += client_p->connection->send.bytes;
590 +    ServerStats.is_sbr += client_p->connection->recv.bytes;
591 +    ServerStats.is_sti += CurrentTime - client_p->connection->firsttime;
592 +
593 +    DLINK_FOREACH(node, connect_items.head)
594 +    {
595 +      struct MaskItem *conf = node->data;
596 +
597 +      if (irccmp(conf->name, client_p->name))
598 +        continue;
599 +
600 +      /*
601 +       * Reset next-connect cycle of all connect{} blocks that match
602 +       * this servername.
603 +       */
604 +      conf->until = CurrentTime + conf->class->con_freq;
605 +    }
606 +  }
607 +  else
608 +    ++ServerStats.is_ni;
609 +
610 +  if (tls_isusing(&client_p->connection->fd->ssl))
611 +    tls_shutdown(&client_p->connection->fd->ssl);
612 +
613 +  if (client_p->connection->fd)
614 +  {
615 +    fd_close(client_p->connection->fd);
616 +    client_p->connection->fd = NULL;
617 +  }
618 +
619 +  dbuf_clear(&client_p->connection->buf_sendq);
620 +  dbuf_clear(&client_p->connection->buf_recvq);
621 +
622 +  xfree(client_p->connection->password);
623 +  client_p->connection->password = NULL;
624 +
625 +  conf_detach(client_p, CONF_CLIENT | CONF_OPER | CONF_SERVER);
626 + }
627 +
628 + /*
629   * Exit one client, local or remote. Assuming all dependents have
630   * been already removed, and socket closed for local client.
631   *
# Line 590 | Line 634 | free_exited_clients(void)
634   static void
635   exit_one_client(struct Client *source_p, const char *comment)
636   {
637 <  dlink_node *node = NULL, *node_next = NULL;
637 >  dlink_node *node, *node_next;
638  
639    assert(!IsMe(source_p));
640    assert(source_p != &me);
641  
642    if (IsClient(source_p))
643    {
644 +    if (HasUMode(source_p, UMODE_OPER))
645 +      --Count.oper;
646 +    if (HasUMode(source_p, UMODE_INVISIBLE))
647 +      --Count.invisi;
648 +
649      dlinkDelete(&source_p->lnode, &source_p->servptr->serv->client_list);
650      dlinkDelete(&source_p->node, &global_client_list);
651  
# Line 613 | Line 662 | exit_one_client(struct Client *source_p,
662      DLINK_FOREACH_SAFE(node, node_next, source_p->channel.head)
663        remove_user_from_channel(node->data);
664  
665 <    client_clear_svstags(source_p);
665 >    svstag_clear_list(&source_p->svstags);
666  
667 <    whowas_add_history(source_p, 0);
667 >    whowas_add_history(source_p, false);
668      whowas_off_history(source_p);
669  
670      watch_check_hash(source_p, RPL_LOGOFF);
622
623    if (MyConnect(source_p))
624    {
625      clear_invites_client(source_p);
626      del_all_accepts(source_p);
627    }
671    }
672    else if (IsServer(source_p))
673    {
674 <    dlinkDelete(&source_p->lnode, &source_p->servptr->serv->server_list);
675 <    dlinkDelete(&source_p->node, &global_client_list);
674 >    sendto_realops_flags(UMODE_EXTERNAL, L_ALL, SEND_NOTICE,
675 >                         "Server %s split from %s",
676 >                         source_p->name, source_p->servptr->name);
677  
678 <    if ((node = dlinkFindDelete(&global_server_list, source_p)))
679 <      free_dlink_node(node);
678 >    dlinkDelete(&source_p->lnode, &source_p->servptr->serv->server_list);
679 >    dlinkDelete(&source_p->node, &global_server_list);
680    }
681  
682    /* Remove source_p from the client lists */
# Line 642 | Line 686 | exit_one_client(struct Client *source_p,
686    if (source_p->name[0])
687      hash_del_client(source_p);
688  
689 <  if (HasFlag(source_p, FLAGS_USERHOST))
690 <    userhost_del(source_p->username, source_p->host, !MyConnect(source_p));
691 <
692 <  update_client_exit_stats(source_p);
689 >  if (HasFlag(source_p, FLAGS_IPHASH))
690 >  {
691 >    DelFlag(source_p, FLAGS_IPHASH);
692 >    ipcache_record_remove(&source_p->ip, MyConnect(source_p));
693 >  }
694  
695    /* Check to see if the client isn't already on the dead list */
696    assert(dlinkFind(&dead_list, source_p) == NULL);
697  
698 <  /* add to dead client dlist */
698 >  /* Add to dead client dlist */
699    SetDead(source_p);
700    dlinkAdd(source_p, make_dlink_node(), &dead_list);
701   }
# Line 664 | Line 709 | exit_one_client(struct Client *source_p,
709   static void
710   recurse_remove_clients(struct Client *source_p, const char *comment)
711   {
712 <  dlink_node *node = NULL, *node_next = NULL;
712 >  dlink_node *node, *node_next;
713  
714    DLINK_FOREACH_SAFE(node, node_next, source_p->serv->client_list.head)
715      exit_one_client(node->data, comment);
# Line 696 | Line 741 | recurse_remove_clients(struct Client *so
741   void
742   exit_client(struct Client *source_p, const char *comment)
743   {
699  dlink_node *node = NULL;
700
744    assert(!IsMe(source_p));
745    assert(source_p != &me);
746  
747    if (MyConnect(source_p))
748    {
749 <    /* DO NOT REMOVE. exit_client can be called twice after a failed
750 <     * read/write.
749 >    /*
750 >     * DO NOT REMOVE. exit_client can be called twice after a failed read/write.
751       */
752      if (HasFlag(source_p, FLAGS_CLOSING))
753        return;
754  
755      AddFlag(source_p, FLAGS_CLOSING);
756  
757 <    if (HasFlag(source_p, FLAGS_IPHASH))
757 >    if (source_p->connection->auth)
758      {
759 <      DelFlag(source_p, FLAGS_IPHASH);
760 <      ipcache_remove_address(&source_p->connection->ip);
759 >      auth_delete(source_p->connection->auth);
760 >      source_p->connection->auth = NULL;
761      }
762  
720    delete_auth(&source_p->connection->auth);
721
763      if (IsClient(source_p))
764      {
765 <      time_t on_for = CurrentTime - source_p->connection->firsttime;
725 <
726 <      assert(Count.local > 0);
727 <
728 <      --Count.local;
765 >      dlink_node *node;
766  
767        if (HasUMode(source_p, UMODE_OPER))
768          if ((node = dlinkFindDelete(&oper_list, source_p)))
# Line 737 | Line 774 | exit_client(struct Client *source_p, con
774        if (source_p->connection->list_task)
775          free_list_task(source_p);
776  
777 +      clear_invite_list(&source_p->connection->invited);
778 +      del_all_accepts(source_p);
779        watch_del_watch_list(source_p);
780  
781        sendto_realops_flags(UMODE_CCONN, L_ALL, SEND_NOTICE,
782                             "Client exiting: %s (%s@%s) [%s] [%s]",
783 <                           source_p->name, source_p->username, source_p->host,
783 >                           source_p->name, source_p->username, source_p->realhost,
784                             source_p->sockhost, comment);
785  
786 <      ilog(LOG_TYPE_USER, "%s (%3u:%02u:%02u): %s!%s@%s %ju/%ju",
787 <           date_ctime(source_p->connection->firsttime), (unsigned int)(on_for / 3600),
788 <           (unsigned int)((on_for % 3600)/60), (unsigned int)(on_for % 60),
786 >      ilog(LOG_TYPE_USER, "%s (%ju): %s!%s@%s %s %s %ju/%ju :%s",
787 >           date_ctime(source_p->connection->firsttime),
788 >           CurrentTime - source_p->connection->firsttime,
789             source_p->name, source_p->username, source_p->host,
790 <           source_p->connection->send.bytes>>10,
791 <           source_p->connection->recv.bytes>>10);
790 >           source_p->sockhost, source_p->account,
791 >           source_p->connection->send.bytes >> 10,
792 >           source_p->connection->recv.bytes >> 10, source_p->info);
793      }
794      else if (IsServer(source_p))
795      {
756      assert(Count.myserver > 0);
757
758      --Count.myserver;
759
796        assert(dlinkFind(&local_server_list, source_p));
797        dlinkDelete(&source_p->connection->lclient_node, &local_server_list);
798      }
# Line 772 | Line 808 | exit_client(struct Client *source_p, con
808        {
809          if (!HasFlag(source_p, FLAGS_SQUIT))
810          {
811 <          /* for them, we are exiting the network */
811 >          /* For them, we are exiting the network */
812            sendto_one(source_p, ":%s SQUIT %s :%s",
813                       me.id, me.id, comment);
814          }
# Line 782 | Line 818 | exit_client(struct Client *source_p, con
818                   source_p->host, comment);
819      }
820  
821 <    close_connection(source_p);
821 >    client_close_connection(source_p);
822    }
823    else if (IsClient(source_p) && HasFlag(source_p->servptr, FLAGS_EOB))
824      sendto_realops_flags(UMODE_FARCONNECT, L_ALL, SEND_NOTICE,
825                           "Client exiting at %s: %s (%s@%s) [%s] [%s]",
826                           source_p->servptr->name, source_p->name,
827 <                         source_p->username, source_p->host, source_p->sockhost, comment);
827 >                         source_p->username, source_p->realhost, source_p->sockhost, comment);
828  
829    if (IsServer(source_p))
830    {
# Line 799 | Line 835 | exit_client(struct Client *source_p, con
835  
836      if (ConfigServerHide.hide_servers)
837        /*
838 <       * Set netsplit message to "*.net *.split" to still show
839 <       * that its a split, but hide the servers splitting
838 >       * Set netsplit message to "*.net *.split" to still show that it's a split,
839 >       * but hide the servers splitting.
840         */
841        strlcpy(splitstr, "*.net *.split", sizeof(splitstr));
842      else
# Line 828 | Line 864 | exit_client(struct Client *source_p, con
864      }
865    }
866    else if (IsClient(source_p) && !HasFlag(source_p, FLAGS_KILLED))
867 <    sendto_server(source_p->from, 0, 0, ":%s QUIT :%s",
832 <                  source_p->id, comment);
867 >    sendto_server(source_p->from, 0, 0, ":%s QUIT :%s", source_p->id, comment);
868  
869    /* The client *better* be off all of the lists */
870    assert(dlinkFind(&unknown_list, source_p) == NULL);
871    assert(dlinkFind(&local_client_list, source_p) == NULL);
872    assert(dlinkFind(&local_server_list, source_p) == NULL);
873    assert(dlinkFind(&oper_list, source_p) == NULL);
874 +  assert(dlinkFind(&listing_client_list, source_p) == NULL);
875  
876    exit_one_client(source_p, comment);
877   }
# Line 882 | Line 918 | dead_link_on_read(struct Client *client_
918    dbuf_clear(&client_p->connection->buf_recvq);
919    dbuf_clear(&client_p->connection->buf_sendq);
920  
921 <  current_error = get_sockerr(client_p->connection->fd.fd);
921 >  current_error = comm_get_sockerr(client_p->connection->fd->fd);
922  
923    if (IsServer(client_p) || IsHandshake(client_p))
924    {
925      if (error == 0)
926      {
891      /* Admins get the real IP */
927        sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
928                             "Server %s closed the connection",
929 <                           get_client_name(client_p, SHOW_IP));
895 <
896 <      /* Opers get a masked IP */
929 >                           client_get_name(client_p, SHOW_IP));
930        sendto_realops_flags(UMODE_SERVNOTICE, L_OPER, SEND_NOTICE,
931                             "Server %s closed the connection",
932 <                           get_client_name(client_p, MASK_IP));
900 <
932 >                           client_get_name(client_p, MASK_IP));
933        ilog(LOG_TYPE_IRCD, "Server %s closed the connection",
934 <           get_client_name(client_p, SHOW_IP));
934 >           client_get_name(client_p, SHOW_IP));
935      }
936      else
937      {
938 <      report_error(L_ADMIN, "Lost connection to %s: %s",
939 <                   get_client_name(client_p, SHOW_IP), current_error);
940 <      report_error(L_OPER, "Lost connection to %s: %s",
941 <                   get_client_name(client_p, MASK_IP), current_error);
938 >      sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
939 >                           "Lost connection to %s: %s",
940 >                           client_get_name(client_p, SHOW_IP), strerror(current_error));
941 >      sendto_realops_flags(UMODE_SERVNOTICE, L_OPER, SEND_NOTICE,
942 >                           "Lost connection to %s: %s",
943 >                           client_get_name(client_p, MASK_IP), strerror(current_error));
944 >      ilog(LOG_TYPE_IRCD, "Lost connection to %s: %s",
945 >           client_get_name(client_p, SHOW_IP), strerror(current_error));
946      }
947  
948      sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
# Line 936 | Line 972 | exit_aborted_clients(void)
972      target_p = ptr->data;
973      eac_next = ptr->next;
974  
975 +    dlinkDelete(ptr, &abort_list);
976 +    free_dlink_node(ptr);
977 +
978      if (target_p == NULL)
979      {
980        sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
981                             "Warning: null client on abort_list!");
943      dlinkDelete(ptr, &abort_list);
944      free_dlink_node(ptr);
982        continue;
983      }
984  
948    dlinkDelete(ptr, &abort_list);
949
985      if (HasFlag(target_p, FLAGS_SENDQEX))
986        notice = "Max SendQ exceeded";
987      else
988        notice = "Write error: connection closed";
989  
990      exit_client(target_p, notice);
956    free_dlink_node(ptr);
991    }
992   }
993  
# Line 972 | Line 1006 | del_accept(struct split_nuh_item *accept
1006   {
1007    dlinkDelete(&accept_p->node, &client_p->connection->acceptlist);
1008  
1009 <  MyFree(accept_p->nickptr);
1010 <  MyFree(accept_p->userptr);
1011 <  MyFree(accept_p->hostptr);
1012 <  MyFree(accept_p);
1009 >  xfree(accept_p->nickptr);
1010 >  xfree(accept_p->userptr);
1011 >  xfree(accept_p->hostptr);
1012 >  xfree(accept_p);
1013   }
1014  
1015   struct split_nuh_item *
1016   find_accept(const char *nick, const char *user,
1017              const char *host, struct Client *client_p,
1018 <            int (*cmpfunc)(const char *, const char *))
1018 >            int (*compare)(const char *, const char *))
1019   {
1020 <  dlink_node *node = NULL;
1020 >  dlink_node *node;
1021  
1022    DLINK_FOREACH(node, client_p->connection->acceptlist.head)
1023    {
1024      struct split_nuh_item *accept_p = node->data;
1025  
1026 <    if (!cmpfunc(accept_p->nickptr, nick) &&
1027 <        !cmpfunc(accept_p->userptr, user) &&
1028 <        !cmpfunc(accept_p->hostptr, host))
1026 >    if (compare(accept_p->nickptr, nick) == 0 &&
1027 >        compare(accept_p->userptr, user) == 0 &&
1028 >        compare(accept_p->hostptr, host) == 0)
1029        return accept_p;
1030    }
1031  
# Line 1005 | Line 1039 | find_accept(const char *nick, const char
1039   * output       - 1 if accept this message 0 if not
1040   * side effects - See if source is on target's allow list
1041   */
1042 < int
1042 > bool
1043   accept_message(struct Client *source,
1044                 struct Client *target)
1045   {
1046 <  dlink_node *node = NULL;
1046 >  dlink_node *node;
1047  
1048    if (HasFlag(source, FLAGS_SERVICE) ||
1049        (HasUMode(source, UMODE_OPER) && ConfigGeneral.opers_bypass_callerid))
1050 <    return 1;
1050 >    return true;
1051  
1052    if (source == target || find_accept(source->name, source->username,
1053                                        source->host, target, match))
1054 <    return 1;
1054 >    return true;
1055  
1056    if (!HasUMode(target, UMODE_CALLERID) && HasUMode(target, UMODE_SOFTCALLERID))
1057      DLINK_FOREACH(node, target->channel.head)
1058        if (IsMember(source, ((struct Membership *)node->data)->chptr))
1059 <        return 1;
1059 >        return true;
1060  
1061 <  return 0;
1061 >  return false;
1062   }
1063  
1064   /* del_all_accepts()
# Line 1036 | Line 1070 | accept_message(struct Client *source,
1070   void
1071   del_all_accepts(struct Client *client_p)
1072   {
1073 <  dlink_node *node = NULL, *node_next = NULL;
1073 >  dlink_node *node, *node_next;
1074  
1075    DLINK_FOREACH_SAFE(node, node_next, client_p->connection->acceptlist.head)
1076      del_accept(node->data, client_p);
# Line 1047 | Line 1081 | client_get_idle_time(const struct Client
1081                       const struct Client *target_p)
1082   {
1083    unsigned int idle = 0;
1084 <  unsigned int min_idle = 0;
1051 <  unsigned int max_idle = 0;
1052 <  const struct ClassItem *const class = get_class_ptr(&target_p->connection->confs);
1084 >  const struct ClassItem *const class = class_get_ptr(&target_p->connection->confs);
1085  
1086    if (!(class->flags & CLASS_FLAGS_FAKE_IDLE) || target_p == source_p)
1087      return CurrentTime - target_p->connection->last_privmsg;
# Line 1058 | Line 1090 | client_get_idle_time(const struct Client
1090        !(class->flags & CLASS_FLAGS_HIDE_IDLE_FROM_OPERS))
1091      return CurrentTime - target_p->connection->last_privmsg;
1092  
1093 <  min_idle = class->min_idle;
1094 <  max_idle = class->max_idle;
1093 >  const unsigned int min_idle = class->min_idle;
1094 >  const unsigned int max_idle = class->max_idle;
1095  
1096    if (min_idle == max_idle)
1097      return min_idle;
# Line 1069 | Line 1101 | client_get_idle_time(const struct Client
1101    else
1102      idle = CurrentTime - target_p->connection->last_privmsg;
1103  
1104 <  if (!max_idle)
1073 <    idle = 0;
1074 <  else
1104 >  if (max_idle)
1105      idle %= max_idle;
1106 +  else
1107 +    idle = 0;
1108  
1109    if (idle < min_idle)
1110      idle = min_idle + (idle % (max_idle - min_idle));
# Line 1096 | Line 1128 | client_init(void)
1128      .when = 5
1129    };
1130  
1099  client_pool = mp_pool_new(sizeof(struct Client), MP_CHUNK_SIZE_CLIENT);
1100  connection_pool = mp_pool_new(sizeof(struct Connection), MP_CHUNK_SIZE_CONNECTION);
1131    event_add(&event_ping, NULL);
1132   }

Comparing ircd-hybrid/trunk/src/client.c (property svn:keywords):
Revision 6963 by michael, Fri Dec 18 19:34:18 2015 UTC vs.
Revision 8664 by michael, Thu Nov 22 14:26:32 2018 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

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