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

Comparing:
ircd-hybrid/src/send.c (file contents), Revision 33 by knight, Sun Oct 2 20:50:00 2005 UTC vs.
ircd-hybrid-7.3/src/send.c (file contents), Revision 1086 by michael, Sat Mar 13 23:59:10 2010 UTC

# Line 23 | Line 23
23   */
24  
25   #include "stdinc.h"
26 < #include "tools.h"
26 > #include "list.h"
27   #include "send.h"
28   #include "channel.h"
29   #include "client.h"
# Line 38 | Line 38
38   #include "s_serv.h"
39   #include "sprintf_irc.h"
40   #include "s_conf.h"
41 #include "list.h"
41   #include "s_log.h"
42   #include "memory.h"
43   #include "hook.h"
44   #include "irc_getnameinfo.h"
45   #include "packet.h"
46  
48 #define LOG_BUFSIZE 2048
47  
48   struct Callback *iosend_cb = NULL;
49   struct Callback *iosendctrl_cb = NULL;
50 + static unsigned int current_serial = 0;
51  
53 static void send_message(struct Client *, char *, int);
54 static void send_message_remote(struct Client *, struct Client *, char *, int);
55
56 static unsigned long current_serial = 0L;
52  
53   /* send_format()
54   *
# Line 87 | Line 82 | send_format(char *lsendbuf, int bufsize,
82  
83    lsendbuf[len++] = '\r';
84    lsendbuf[len++] = '\n';
85 <  return (len);
85 >  return len;
86 > }
87 >
88 > /*
89 > * iosend_default - append a packet to the client's sendq.
90 > */
91 > void *
92 > iosend_default(va_list args)
93 > {
94 >  struct Client *to = va_arg(args, struct Client *);
95 >  int length = va_arg(args, int);
96 >  char *buf = va_arg(args, char *);
97 >
98 >  dbuf_put(&to->localClient->buf_sendq, buf, length);
99 >  return NULL;
100   }
101  
102   /*
# Line 98 | Line 107 | send_format(char *lsendbuf, int bufsize,
107   static void
108   send_message(struct Client *to, char *buf, int len)
109   {
110 < #ifdef INVARIANTS
111 <  if (IsMe(to))
103 <  {
104 <    sendto_realops_flags(UMODE_ALL, L_ALL,
105 <                         "Trying to send message to myself!");
106 <    return;
107 <  }
108 < #endif
110 >  assert(!IsMe(to));
111 >  assert(to != &me);
112  
113    if (dbuf_length(&to->localClient->buf_sendq) + len > get_sendq(to))
114    {
# Line 121 | Line 124 | send_message(struct Client *to, char *bu
124      return;
125    }
126  
127 <  dbuf_put(&to->localClient->buf_sendq, buf, len);
127 >  execute_callback(iosend_cb, to, len, buf);
128  
129    /*
130     ** Update statistics. The following is slightly incorrect
# Line 159 | Line 162 | send_message_remote(struct Client *to, s
162      return;
163    }
164  
162  if (ServerInfo.hub && IsCapable(to, CAP_LL))
163  {
164    if (((from->lazyLinkClientExists &
165          to->localClient->serverMask) == 0))
166      client_burst_if_needed(to, from);
167  }
168
165    /* Optimize by checking if (from && to) before everything */
166    /* we set to->from up there.. */
167  
# Line 185 | Line 181 | send_message_remote(struct Client *to, s
181                           from->name, from->username, from->host,
182                           to->from->name);
183  
184 <    sendto_server(NULL, to, NULL, CAP_TS6, NOCAPS, NOFLAGS,
184 >    sendto_server(NULL, NULL, CAP_TS6, NOCAPS,
185                    ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
186                    me.id, to->name, me.name, to->name,
187                    to->username, to->host, to->from->name);
188 <    sendto_server(NULL, to, NULL, NOCAPS, CAP_TS6, NOFLAGS,
188 >    sendto_server(NULL, NULL, NOCAPS, CAP_TS6,
189                    ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
190                    me.name, to->name, me.name, to->name,
191                    to->username, to->host, to->from->name);
# Line 281 | Line 277 | send_queued_write(struct Client *to)
277                errno = EWOULDBLOCK;
278              case SSL_ERROR_SYSCALL:
279                break;
280 <
280 >            case SSL_ERROR_SSL:
281 >              if (errno == EAGAIN)
282 >                break;
283              default:
284                retlen = errno = 0;  /* either an SSL-specific error or EOF */
285            }
# Line 291 | Line 289 | send_queued_write(struct Client *to)
289          retlen = send(to->localClient->fd.fd, first->data, first->size, 0);
290  
291        if (retlen <= 0)
294      {
295 #ifdef _WIN32
296        errno = WSAGetLastError();
297 #endif
292          break;
299      }
293  
301      execute_callback(iosend_cb, to, retlen, first->data);
294        dbuf_delete(&to->localClient->buf_sendq, retlen);
295  
296        /* We have some data written .. update counters */
# Line 460 | Line 452 | sendto_channel_butone(struct Client *one
452                        struct Channel *chptr, const char *command,
453                        const char *pattern, ...)
454   {
455 <  va_list args;
455 >  va_list alocal, aremote, auid;
456    char local_buf[IRCD_BUFSIZE];
457    char remote_buf[IRCD_BUFSIZE];
458    char uid_buf[IRCD_BUFSIZE];
459    int local_len, remote_len, uid_len;
460 <  dlink_node *ptr;
469 <  dlink_node *ptr_next;
470 <  struct Client *target_p;
460 >  dlink_node *ptr = NULL, *ptr_next = NULL;
461  
462    if (IsServer(from))
463      local_len = ircsprintf(local_buf, ":%s %s %s ",
# Line 481 | Line 471 | sendto_channel_butone(struct Client *one
471    uid_len = ircsprintf(uid_buf, ":%s %s %s ",
472                         ID(from), command, chptr->chname);
473  
474 <  va_start(args, pattern);
474 >  va_start(alocal, pattern);
475 >  va_start(aremote, pattern);
476 >  va_start(auid, pattern);
477    local_len += send_format(&local_buf[local_len], IRCD_BUFSIZE - local_len,
478 <                           pattern, args);
478 >                           pattern, alocal);
479    remote_len += send_format(&remote_buf[remote_len], IRCD_BUFSIZE - remote_len,
480 <                            pattern, args);
480 >                            pattern, aremote);
481    uid_len += send_format(&uid_buf[uid_len], IRCD_BUFSIZE - uid_len, pattern,
482 <                         args);
483 <  va_end(args);
482 >                         auid);
483 >  va_end(auid);
484 >  va_end(aremote);
485 >  va_end(alocal);
486  
487    ++current_serial;
488  
489    DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head)
490    {
491 <    target_p = ((struct Membership *)ptr->data)->client_p;
492 <    assert(target_p != NULL);
491 >    struct Client *target_p = ((struct Membership *)ptr->data)->client_p;
492 >
493 >    assert(IsClient(target_p));
494  
495      if (IsDefunct(target_p) || IsDeaf(target_p) || target_p->from == one)
496        continue;
497  
498 <    if (MyClient(target_p))
498 >    if (MyConnect(target_p))
499      {
500 <      if (target_p->serial != current_serial)
500 >      if (target_p->localClient->serial != current_serial)
501        {
502          send_message(target_p, local_buf, local_len);
503 <        target_p->serial = current_serial;
503 >        target_p->localClient->serial = current_serial;
504        }
505      }
506      else
# Line 513 | Line 508 | sendto_channel_butone(struct Client *one
508        /* Now check whether a message has been sent to this
509         * remote link already
510         */
511 <      if (target_p->from->serial != current_serial)
511 >      if (target_p->from->localClient->serial != current_serial)
512        {
513          if (IsCapable(target_p->from, CAP_TS6))
514            send_message_remote(target_p->from, from, uid_buf, uid_len);
515          else
516            send_message_remote(target_p->from, from, remote_buf, remote_len);
517 <        target_p->from->serial = current_serial;
517 >        target_p->from->localClient->serial = current_serial;
518        }
519      }
520    }
# Line 528 | Line 523 | sendto_channel_butone(struct Client *one
523   /* sendto_server()
524   *
525   * inputs       - pointer to client to NOT send to
526 < *              - pointer to source client required by LL (if any)
532 < *              - pointer to channel required by LL (if any)
526 > *              - pointer to channel
527   *              - caps or'd together which must ALL be present
528   *              - caps or'd together which must ALL NOT be present
535 *              - LL flags: LL_ICLIENT | LL_ICHAN
529   *              - printf style format string
530   *              - args to format string
531   * output       - NONE
532   * side effects - Send a message to all connected servers, except the
533   *                client 'one' (if non-NULL), as long as the servers
534   *                support ALL capabs in 'caps', and NO capabs in 'nocaps'.
542 *                If the server is a lazylink client, then it must know
543 *                about source_p if non-NULL (unless LL_ICLIENT is specified,
544 *                when source_p will be introduced where required) and
545 *                chptr if non-NULL (unless LL_ICHANNEL is specified, when
546 *                chptr will be introduced where required).
547 *                Note: nothing will be introduced to a LazyLeaf unless
548 *                the message is actually sent.
535   *            
536   * This function was written in an attempt to merge together the other
537   * billion sendto_*serv*() functions, which sprung up with capabs,
# Line 553 | Line 539 | sendto_channel_butone(struct Client *one
539   * -davidt
540   */
541   void
542 < sendto_server(struct Client *one, struct Client *source_p,
543 <              struct Channel *chptr, unsigned long caps,
544 <              unsigned long nocaps, unsigned long llflags,
542 > sendto_server(struct Client *one, const struct Channel *chptr,
543 >              const unsigned int caps,
544 >              const unsigned int nocaps,
545                const char *format, ...)
546   {
547    va_list args;
548 <  struct Client *client_p;
563 <  dlink_node *ptr;
548 >  dlink_node *ptr = NULL;
549    char buffer[IRCD_BUFSIZE];
550 <  int len;
550 >  int len = 0;
551  
552 <  if (chptr != NULL)
553 <  {
569 <    if (chptr->chname[0] != '#')
570 <      return;
571 <  }
552 >  if (chptr && chptr->chname[0] != '#')
553 >    return;
554  
555    va_start(args, format);
556    len = send_format(buffer, IRCD_BUFSIZE, format, args);
# Line 576 | Line 558 | sendto_server(struct Client *one, struct
558  
559    DLINK_FOREACH(ptr, serv_list.head)
560    {
561 <    client_p = ptr->data;
561 >    struct Client *client_p = ptr->data;
562  
563      /* If dead already skip */
564      if (IsDead(client_p))
# Line 591 | Line 573 | sendto_server(struct Client *one, struct
573      if ((client_p->localClient->caps & nocaps) != 0)
574        continue;
575  
594    if (ServerInfo.hub && IsCapable(client_p, CAP_LL))
595    {
596      /* check LL channel */
597      if (chptr != NULL &&
598          ((chptr->lazyLinkChannelExists &
599            client_p->localClient->serverMask) == 0))
600      {
601        /* Only introduce the channel if we really will send this message */
602        if (!(llflags & LL_ICLIENT) && source_p &&
603            ((source_p->lazyLinkClientExists &
604              client_p->localClient->serverMask) == 0))
605          continue; /* we can't introduce the unknown source_p, skip */
606
607        if (llflags & LL_ICHAN)
608          burst_channel(client_p, chptr);
609        else
610          continue; /* we can't introduce the unknown chptr, skip */
611      }
612      /* check LL client */
613      if (source_p &&
614          ((source_p->lazyLinkClientExists &
615            client_p->localClient->serverMask) == 0))
616      {
617        if (llflags & LL_ICLIENT)
618          client_burst_if_needed(client_p,source_p);
619        else
620          continue; /* we can't introduce the unknown source_p, skip */
621      }
622    }
576      send_message(client_p, buffer, len);
577    }
578   }
# Line 657 | Line 610 | sendto_common_channels_local(struct Clie
610      chptr = ((struct Membership *) cptr->data)->chptr;
611      assert(chptr != NULL);
612  
613 <    DLINK_FOREACH(uptr, chptr->locmembers.head)
613 >    DLINK_FOREACH(uptr, chptr->members.head)
614      {
615        ms = uptr->data;
616        target_p = ms->client_p;
617        assert(target_p != NULL);
618  
619 <      if (target_p == user || IsDefunct(target_p) ||
620 <          target_p->serial == current_serial)
619 >      if (!MyConnect(target_p) || target_p == user || IsDefunct(target_p) ||
620 >          target_p->localClient->serial == current_serial)
621          continue;
622  
623 <      target_p->serial = current_serial;
623 >      target_p->localClient->serial = current_serial;
624        send_message(target_p, buffer, len);
625      }
626    }
627  
628    if (touser && MyConnect(user) && !IsDead(user) &&
629 <      user->serial != current_serial)
629 >      user->localClient->serial != current_serial)
630      send_message(user, buffer, len);
631   }
632  
# Line 702 | Line 655 | sendto_channel_local(int type, int nodea
655    len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
656    va_end(args);
657  
658 <  DLINK_FOREACH(ptr, chptr->locmembers.head)
658 >  DLINK_FOREACH(ptr, chptr->members.head)
659    {
660      ms = ptr->data;
661      target_p = ms->client_p;
# Line 710 | Line 663 | sendto_channel_local(int type, int nodea
663      if (type != 0 && (ms->flags & type) == 0)
664        continue;
665  
666 <    if (IsDefunct(target_p) || (nodeaf && IsDeaf(target_p)))
666 >    if (!MyConnect(target_p) || IsDefunct(target_p) ||
667 >        (nodeaf && IsDeaf(target_p)))
668        continue;
669  
670      send_message(target_p, buffer, len);
# Line 744 | Line 698 | sendto_channel_local_butone(struct Clien
698    len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
699    va_end(args);
700  
701 <  DLINK_FOREACH(ptr, chptr->locmembers.head)      
701 >  DLINK_FOREACH(ptr, chptr->members.head)      
702    {  
703      ms = ptr->data;
704      target_p = ms->client_p;
# Line 752 | Line 706 | sendto_channel_local_butone(struct Clien
706      if (type != 0 && (ms->flags & type) == 0)
707        continue;
708  
709 <    if (target_p == one || IsDefunct(target_p) || IsDeaf(target_p))
709 >    if (!MyConnect(target_p) || target_p == one ||
710 >        IsDefunct(target_p) || IsDeaf(target_p))
711        continue;
712      send_message(target_p, buffer, len);
713    }
# Line 771 | Line 726 | sendto_channel_local_butone(struct Clien
726   *                remote to this server.
727   */
728   void
729 < sendto_channel_remote(struct Client *one, struct Client *from, int type, int caps,
730 <                      int nocaps, struct Channel *chptr, const char *pattern, ...)
729 > sendto_channel_remote(struct Client *one, struct Client *from, int type,
730 >                      const unsigned int caps, const unsigned int nocaps,
731 >                      struct Channel *chptr, const char *pattern, ...)
732   {
733    va_list args;
734    char buffer[IRCD_BUFSIZE];
# Line 785 | Line 741 | sendto_channel_remote(struct Client *one
741    len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
742    va_end(args);
743  
744 +  ++current_serial;
745 +
746    DLINK_FOREACH(ptr, chptr->members.head)
747    {
748      ms = ptr->data;
# Line 801 | Line 759 | sendto_channel_remote(struct Client *one
759          ((target_p->from->localClient->caps & caps) != caps) ||
760          ((target_p->from->localClient->caps & nocaps) != 0))
761        continue;
762 <
763 <    send_message(target_p, buffer, len);
762 >    if (target_p->from->localClient->serial != current_serial)
763 >    {
764 >      send_message(target_p, buffer, len);
765 >      target_p->from->localClient->serial = current_serial;
766 >    }
767    }
768   }
769  
# Line 827 | Line 788 | static int
788   match_it(const struct Client *one, const char *mask, int what)
789   {
790    if (what == MATCH_HOST)
791 <    return(match(mask, one->host));
791 >    return match(mask, one->host);
792  
793 <  return(match(mask, one->servptr->name));
793 >  return match(mask, one->servptr->name);
794   }
795  
796   /* sendto_match_butone()
# Line 843 | Line 804 | void
804   sendto_match_butone(struct Client *one, struct Client *from, char *mask,
805                      int what, const char *pattern, ...)
806   {
807 <  va_list args;
807 >  va_list alocal, aremote;
808    struct Client *client_p;
809    dlink_node *ptr, *ptr_next;
810    char local_buf[IRCD_BUFSIZE], remote_buf[IRCD_BUFSIZE];
# Line 851 | Line 812 | sendto_match_butone(struct Client *one,
812                               from->username, from->host);
813    int remote_len = ircsprintf(remote_buf, ":%s ", from->name);
814  
815 <  va_start(args, pattern);
815 >  va_start(alocal, pattern);
816 >  va_start(aremote, pattern);
817    local_len += send_format(&local_buf[local_len], IRCD_BUFSIZE - local_len,
818 <                           pattern, args);
818 >                           pattern, alocal);
819    remote_len += send_format(&remote_buf[remote_len], IRCD_BUFSIZE - remote_len,
820 <                            pattern, args);
821 <  va_end(args);
820 >                            pattern, aremote);
821 >  va_end(aremote);
822 >  va_end(alocal);
823  
824    /* scan the local clients */
825    DLINK_FOREACH(ptr, local_client_list.head)
# Line 925 | Line 888 | sendto_match_servs(struct Client *source
888    vsnprintf(buffer, sizeof(buffer), pattern, args);
889    va_end(args);
890  
891 <  current_serial++;
891 >  ++current_serial;
892  
893    DLINK_FOREACH(ptr, global_serv_list.head)
894    {
# Line 935 | Line 898 | sendto_match_servs(struct Client *source
898      if (IsMe(target_p) || target_p->from == source_p->from)
899        continue;
900  
901 <    if (target_p->from->serial == current_serial)
901 >    if (target_p->from->localClient->serial == current_serial)
902        continue;
903  
904      if (match(mask, target_p->name))
# Line 944 | Line 907 | sendto_match_servs(struct Client *source
907         * if we set the serial here, then we'll never do a
908         * match() again, if !IsCapable()
909         */
910 <      target_p->from->serial = current_serial;
910 >      target_p->from->localClient->serial = current_serial;
911        found++;
912  
913        if (!IsCapable(target_p->from, cap))
# Line 1012 | Line 975 | sendto_anywhere(struct Client *to, struc
975   void
976   sendto_realops_flags(unsigned int flags, int level, const char *pattern, ...)
977   {
978 <  struct Client *client_p;
978 >  dlink_node *ptr = NULL;
979    char nbuf[IRCD_BUFSIZE];
1017  dlink_node *ptr;
980    va_list args;
981  
982    va_start(args, pattern);
# Line 1023 | Line 985 | sendto_realops_flags(unsigned int flags,
985  
986    DLINK_FOREACH(ptr, oper_list.head)
987    {
988 <    client_p = ptr->data;
988 >    struct Client *client_p = ptr->data;
989      assert(client_p->umodes & UMODE_OPER);
990  
991      /* If we're sending it to opers and theyre an admin, skip.
# Line 1051 | Line 1013 | void
1013   sendto_wallops_flags(unsigned int flags, struct Client *source_p,
1014                       const char *pattern, ...)
1015   {
1016 <  struct Client *client_p;
1055 <  dlink_node *ptr;
1016 >  dlink_node *ptr = NULL;
1017    va_list args;
1018    char buffer[IRCD_BUFSIZE];
1019    int len;
# Line 1069 | Line 1030 | sendto_wallops_flags(unsigned int flags,
1030  
1031    DLINK_FOREACH(ptr, oper_list.head)
1032    {
1033 <    client_p = ptr->data;
1033 >    struct Client *client_p = ptr->data;
1034      assert(client_p->umodes & UMODE_OPER);
1035  
1036      if ((client_p->umodes & flags) && !IsDefunct(client_p))
# Line 1088 | Line 1049 | void
1049   ts_warn(const char *pattern, ...)
1050   {
1051    va_list args;
1052 <  char buffer[LOG_BUFSIZE];
1052 >  char buffer[IRCD_BUFSIZE];
1053    static time_t last = 0;
1054    static int warnings = 0;
1055  
# Line 1111 | Line 1072 | ts_warn(const char *pattern, ...)
1072    }
1073  
1074    va_start(args, pattern);
1075 <  vsprintf_irc(buffer, pattern, args);
1075 >  vsnprintf(buffer, sizeof(buffer), pattern, args);
1076    va_end(args);
1077  
1078    sendto_realops_flags(UMODE_ALL, L_ALL, "%s", buffer);
# Line 1165 | Line 1126 | kill_client_ll_serv_butone(struct Client
1126   {
1127    va_list args;
1128    int have_uid = 0;
1129 <  struct Client *client_p;
1169 <  dlink_node *ptr;
1129 >  dlink_node *ptr = NULL;
1130    char buf_uid[IRCD_BUFSIZE], buf_nick[IRCD_BUFSIZE];
1131 <  int len_uid = 0, len_nick;
1131 >  int len_uid = 0, len_nick = 0;
1132  
1173  va_start(args, pattern);
1133    if (HasID(source_p) && (me.id[0] != '\0'))
1134    {
1135      have_uid = 1;
1136 +    va_start(args, pattern);
1137      len_uid = ircsprintf(buf_uid, ":%s KILL %s :", me.id, ID(source_p));
1138      len_uid += send_format(&buf_uid[len_uid], IRCD_BUFSIZE - len_uid, pattern,
1139                             args);
1140 +    va_end(args);
1141    }
1142 +
1143 +  va_start(args, pattern);
1144    len_nick = ircsprintf(buf_nick, ":%s KILL %s :", me.name, source_p->name);
1145    len_nick += send_format(&buf_nick[len_nick], IRCD_BUFSIZE - len_nick, pattern,
1146                            args);
# Line 1185 | Line 1148 | kill_client_ll_serv_butone(struct Client
1148  
1149    DLINK_FOREACH(ptr, serv_list.head)
1150    {
1151 <    client_p = ptr->data;
1151 >    struct Client *client_p = ptr->data;
1152  
1153      if (one != NULL && (client_p == one->from))
1154        continue;
1155      if (IsDefunct(client_p))
1156        continue;
1157  
1158 <    /* XXX perhaps IsCapable should test for localClient itself ? -db */
1159 <    if (client_p->localClient == NULL || !IsCapable(client_p, CAP_LL) ||
1160 <        !ServerInfo.hub ||
1161 <        (source_p->lazyLinkClientExists & client_p->localClient->serverMask))
1199 <    {
1200 <      if (have_uid && IsCapable(client_p, CAP_TS6))
1201 <        send_message(client_p, buf_uid, len_uid);
1202 <      else
1203 <        send_message(client_p, buf_nick, len_nick);
1204 <    }
1158 >    if (have_uid && IsCapable(client_p, CAP_TS6))
1159 >      send_message(client_p, buf_uid, len_uid);
1160 >    else
1161 >      send_message(client_p, buf_nick, len_nick);
1162    }
1163   }

Diff Legend

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