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

Comparing ircd-hybrid/trunk/src/s_serv.c (file contents):
Revision 3274 by michael, Sun Apr 6 12:22:23 2014 UTC vs.
Revision 3335 by michael, Thu Apr 17 18:55:31 2014 UTC

# Line 42 | Line 42
42   #include "conf.h"
43   #include "s_serv.h"
44   #include "log.h"
45 – #include "s_misc.h"
45   #include "s_user.h"
46   #include "send.h"
47   #include "memory.h"
# Line 53 | Line 52
52  
53   dlink_list flatten_links;
54   static dlink_list cap_list = { NULL, NULL, 0 };
56 – static void server_burst(struct Client *);
57 – static void burst_all(struct Client *);
58 – static void send_tb(struct Client *client_p, struct Channel *chptr);
59 –
55   static CNCB serv_connect_callback;
56  
62 – static void burst_members(struct Client *, struct Channel *);
57  
58   /*
59   * write_links_file
# Line 264 | Line 258 | void
258   try_connections(void *unused)
259   {
260    dlink_node *ptr = NULL;
261 <  struct MaskItem *conf;
268 <  int confrq;
261 >  int confrq = 0;
262  
263    /* TODO: change this to set active flag to 0 when added to event! --Habeeb */
264    if (GlobalSetOptions.autoconn == 0)
# Line 273 | Line 266 | try_connections(void *unused)
266  
267    DLINK_FOREACH(ptr, server_items.head)
268    {
269 <    conf = ptr->data;
269 >    struct MaskItem *conf = ptr->data;
270  
271      assert(conf->type == CONF_SERVER);
272  
# Line 471 | Line 464 | add_capability(const char *capab_name, i
464   int
465   delete_capability(const char *capab_name)
466   {
467 <  dlink_node *ptr;
475 <  dlink_node *next_ptr;
476 <  struct Capability *cap;
467 >  dlink_node *ptr = NULL, *ptr_next = NULL;
468  
469 <  DLINK_FOREACH_SAFE(ptr, next_ptr, cap_list.head)
469 >  DLINK_FOREACH_SAFE(ptr, ptr_next, cap_list.head)
470    {
471 <    cap = ptr->data;
471 >    struct Capability *cap = ptr->data;
472  
473 <    if (cap->cap != 0)
473 >    if (cap->cap)
474      {
475 <      if (irccmp(cap->name, capab_name) == 0)
475 >      if (!irccmp(cap->name, capab_name))
476        {
477          default_server_capabs &= ~(cap->cap);
478          dlinkDelete(ptr, &cap_list);
# Line 548 | Line 539 | send_capabilities(struct Client *client_
539    sendto_one(client_p, "CAPAB :%s", msgbuf);
540   }
541  
551 – /* sendnick_TS()
552 – *
553 – * inputs       - client (server) to send nick towards
554 – *          - client to send nick for
555 – * output       - NONE
556 – * side effects - NICK message is sent towards given client_p
557 – */
558 – void
559 – sendnick_TS(struct Client *client_p, struct Client *target_p)
560 – {
561 –  char ubuf[IRCD_BUFSIZE] = "";
562 –
563 –  if (!IsClient(target_p))
564 –    return;
565 –
566 –  send_umode(NULL, target_p, 0, SEND_UMODES, ubuf);
567 –
568 –  if (ubuf[0] == '\0')
569 –  {
570 –    ubuf[0] = '+';
571 –    ubuf[1] = '\0';
572 –  }
573 –
574 –  if (IsCapable(client_p, CAP_SVS))
575 –    sendto_one(client_p, ":%s UID %s %d %lu %s %s %s %s %s %s :%s",
576 –               target_p->servptr->id,
577 –               target_p->name, target_p->hopcount + 1,
578 –               (unsigned long) target_p->tsinfo,
579 –               ubuf, target_p->username, target_p->host,
580 –               (MyClient(target_p) && IsIPSpoof(target_p)) ?
581 –               "0" : target_p->sockhost, target_p->id,
582 –               target_p->svid, target_p->info);
583 –  else
584 –    sendto_one(client_p, ":%s UID %s %d %lu %s %s %s %s %s :%s",
585 –               target_p->servptr->id,
586 –               target_p->name, target_p->hopcount + 1,
587 –               (unsigned long) target_p->tsinfo,
588 –               ubuf, target_p->username, target_p->host,
589 –               (MyClient(target_p) && IsIPSpoof(target_p)) ?
590 –               "0" : target_p->sockhost, target_p->id, target_p->info);
591 –
592 –  if (!EmptyString(target_p->certfp))
593 –    sendto_one(client_p, ":%s CERTFP %s", target_p->id, target_p->certfp);
594 –
595 –  if (target_p->away[0])
596 –    sendto_one(client_p, ":%s AWAY :%s", target_p->id, target_p->away);
597 –
598 – }
599 –
542   /*
543   * show_capabilities - show current server capabilities
544   *
# Line 642 | Line 584 | make_server(struct Client *client_p)
584    return client_p->serv;
585   }
586  
645 – /* server_estab()
646 – *
647 – * inputs       - pointer to a struct Client
648 – * output       -
649 – * side effects -
650 – */
651 – void
652 – server_estab(struct Client *client_p)
653 – {
654 –  struct MaskItem *conf = NULL;
655 –  char *host;
656 –  const char *inpath;
657 –  static char inpath_ip[HOSTLEN * 2 + USERLEN + 6];
658 –  dlink_node *ptr;
659 – #ifdef HAVE_LIBCRYPTO
660 –  const COMP_METHOD *compression = NULL, *expansion = NULL;
661 – #endif
662 –
663 –  assert(client_p);
664 –
665 –  strlcpy(inpath_ip, get_client_name(client_p, SHOW_IP), sizeof(inpath_ip));
666 –
667 –  inpath = get_client_name(client_p, MASK_IP); /* "refresh" inpath with host */
668 –  host   = client_p->name;
669 –
670 –  if ((conf = find_conf_name(&client_p->localClient->confs, host, CONF_SERVER))
671 –      == NULL)
672 –  {
673 –    /* This shouldn't happen, better tell the ops... -A1kmm */
674 –    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
675 –                         "Warning: Lost connect{} block "
676 –                         "for server %s(this shouldn't happen)!", host);
677 –    exit_client(client_p, "Lost connect{} block!");
678 –    return;
679 –  }
680 –
681 –  MyFree(client_p->localClient->passwd);
682 –  client_p->localClient->passwd = NULL;
683 –
684 –  /* Its got identd, since its a server */
685 –  SetGotId(client_p);
686 –
687 –  /* If there is something in the serv_list, it might be this
688 –   * connecting server..
689 –   */
690 –  if (!ServerInfo.hub && serv_list.head)
691 –  {
692 –    if (client_p != serv_list.head->data || serv_list.head->next)
693 –    {
694 –      ++ServerStats.is_ref;
695 –      sendto_one(client_p, "ERROR :I'm a leaf not a hub");
696 –      exit_client(client_p, "I'm a leaf");
697 –      return;
698 –    }
699 –  }
700 –
701 –  if (IsUnknown(client_p))
702 –  {
703 –    sendto_one(client_p, "PASS %s TS %d %s", conf->spasswd, TS_CURRENT, me.id);
704 –
705 –    send_capabilities(client_p, 0);
706 –
707 –    sendto_one(client_p, "SERVER %s 1 :%s%s",
708 –               me.name, ConfigServerHide.hidden ? "(H) " : "", me.info);
709 –  }
710 –
711 –  sendto_one(client_p, "SVINFO %d %d 0 :%lu", TS_CURRENT, TS_MIN,
712 –             (unsigned long)CurrentTime);
713 –
714 –  /* XXX Does this ever happen? I don't think so -db */
715 –  detach_conf(client_p, CONF_OPER);
716 –
717 –  /* *WARNING*
718 –  **    In the following code in place of plain server's
719 –  **    name we send what is returned by get_client_name
720 –  **    which may add the "sockhost" after the name. It's
721 –  **    *very* *important* that there is a SPACE between
722 –  **    the name and sockhost (if present). The receiving
723 –  **    server will start the information field from this
724 –  **    first blank and thus puts the sockhost into info.
725 –  **    ...a bit tricky, but you have been warned, besides
726 –  **    code is more neat this way...  --msa
727 –  */
728 –  client_p->servptr = &me;
729 –
730 –  if (IsClosing(client_p))
731 –    return;
732 –
733 –  SetServer(client_p);
734 –
735 –  /* Some day, all these lists will be consolidated *sigh* */
736 –  dlinkAdd(client_p, &client_p->lnode, &me.serv->server_list);
737 –
738 –  assert(dlinkFind(&unknown_list, client_p));
739 –
740 –  dlink_move_node(&client_p->localClient->lclient_node,
741 –                  &unknown_list, &serv_list);
742 –
743 –  Count.myserver++;
744 –
745 –  dlinkAdd(client_p, make_dlink_node(), &global_serv_list);
746 –  hash_add_client(client_p);
747 –  hash_add_id(client_p);
748 –
749 –  /* doesnt duplicate client_p->serv if allocated this struct already */
750 –  make_server(client_p);
751 –
752 –  /* fixing eob timings.. -gnp */
753 –  client_p->localClient->firsttime = CurrentTime;
754 –
755 –  if (find_matching_name_conf(CONF_SERVICE, client_p->name, NULL, NULL, 0))
756 –    AddFlag(client_p, FLAGS_SERVICE);
757 –
758 –  /* Show the real host/IP to admins */
759 – #ifdef HAVE_LIBCRYPTO
760 –  if (client_p->localClient->fd.ssl)
761 –  {
762 –    compression = SSL_get_current_compression(client_p->localClient->fd.ssl);
763 –    expansion   = SSL_get_current_expansion(client_p->localClient->fd.ssl);
764 –
765 –    sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
766 –                         "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)",
767 –                         inpath_ip, ssl_get_cipher(client_p->localClient->fd.ssl),
768 –                         compression ? SSL_COMP_get_name(compression) : "NONE",
769 –                         expansion ? SSL_COMP_get_name(expansion) : "NONE",
770 –                         show_capabilities(client_p));
771 –    /* Now show the masked hostname/IP to opers */
772 –    sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
773 –                         "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)",
774 –                         inpath, ssl_get_cipher(client_p->localClient->fd.ssl),
775 –                         compression ? SSL_COMP_get_name(compression) : "NONE",
776 –                         expansion ? SSL_COMP_get_name(expansion) : "NONE",
777 –                         show_capabilities(client_p));
778 –    ilog(LOG_TYPE_IRCD, "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)",
779 –         inpath_ip, ssl_get_cipher(client_p->localClient->fd.ssl),
780 –         compression ? SSL_COMP_get_name(compression) : "NONE",
781 –         expansion ? SSL_COMP_get_name(expansion) : "NONE",
782 –         show_capabilities(client_p));
783 –  }
784 –  else
785 – #endif
786 –  {
787 –    sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
788 –                         "Link with %s established: (Capabilities: %s)",
789 –                         inpath_ip, show_capabilities(client_p));
790 –    /* Now show the masked hostname/IP to opers */
791 –    sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
792 –                         "Link with %s established: (Capabilities: %s)",
793 –                         inpath, show_capabilities(client_p));
794 –    ilog(LOG_TYPE_IRCD, "Link with %s established: (Capabilities: %s)",
795 –         inpath_ip, show_capabilities(client_p));
796 –  }
797 –
798 –  fd_note(&client_p->localClient->fd, "Server: %s", client_p->name);
799 –
800 –  sendto_server(client_p, NOCAPS, NOCAPS, ":%s SID %s 2 %s :%s%s",
801 –                me.id, client_p->name, client_p->id,
802 –                IsHidden(client_p) ? "(H) " : "", client_p->info);
803 –
804 –  /*
805 –   * Pass on my client information to the new server
806 –   *
807 –   * First, pass only servers (idea is that if the link gets
808 –   * cancelled beacause the server was already there,
809 –   * there are no NICK's to be cancelled...). Of course,
810 –   * if cancellation occurs, all this info is sent anyway,
811 –   * and I guess the link dies when a read is attempted...? --msa
812 –   *
813 –   * Note: Link cancellation to occur at this point means
814 –   * that at least two servers from my fragment are building
815 –   * up connection this other fragment at the same time, it's
816 –   * a race condition, not the normal way of operation...
817 –   *
818 –   * ALSO NOTE: using the get_client_name for server names--
819 –   *    see previous *WARNING*!!! (Also, original inpath
820 –   *    is destroyed...)
821 –   */
822 –
823 –  DLINK_FOREACH_PREV(ptr, global_serv_list.tail)
824 –  {
825 –    struct Client *target_p = ptr->data;
826 –
827 –    /* target_p->from == target_p for target_p == client_p */
828 –    if (IsMe(target_p) || target_p->from == client_p)
829 –      continue;
830 –
831 –    sendto_one(client_p, ":%s SID %s %d %s :%s%s",
832 –               target_p->servptr->id, target_p->name, target_p->hopcount+1,
833 –               target_p->id, IsHidden(target_p) ? "(H) " : "",
834 –               target_p->info);
835 –
836 –    if (HasFlag(target_p, FLAGS_EOB))
837 –      sendto_one(client_p, ":%s EOB", target_p->id, client_p);
838 –  }
839 –
840 –  server_burst(client_p);
841 – }
842 –
843 – /* server_burst()
844 – *
845 – * inputs       - struct Client pointer server
846 – *              -
847 – * output       - none
848 – * side effects - send a server burst
849 – * bugs         - still too long
850 – */
851 – static void
852 – server_burst(struct Client *client_p)
853 – {
854 –  /* Send it in the shortened format with the TS, if
855 –  ** it's a TS server; walk the list of channels, sending
856 –  ** all the nicks that haven't been sent yet for each
857 –  ** channel, then send the channel itself -- it's less
858 –  ** obvious than sending all nicks first, but on the
859 –  ** receiving side memory will be allocated more nicely
860 –  ** saving a few seconds in the handling of a split
861 –  ** -orabidoo
862 –  */
863 –
864 –  burst_all(client_p);
865 –
866 –  /* EOB stuff is now in burst_all */
867 –  /* Always send a PING after connect burst is done */
868 –  sendto_one(client_p, "PING :%s", me.id);
869 – }
870 –
871 – /* burst_all()
872 – *
873 – * inputs       - pointer to server to send burst to
874 – * output       - NONE
875 – * side effects - complete burst of channels/nicks is sent to client_p
876 – */
877 – static void
878 – burst_all(struct Client *client_p)
879 – {
880 –  dlink_node *ptr = NULL;
881 –
882 –  DLINK_FOREACH(ptr, global_channel_list.head)
883 –  {
884 –    struct Channel *chptr = ptr->data;
885 –
886 –    if (dlink_list_length(&chptr->members))
887 –    {
888 –      burst_members(client_p, chptr);
889 –      send_channel_modes(client_p, chptr);
890 –
891 –      if (IsCapable(client_p, CAP_TBURST))
892 –        send_tb(client_p, chptr);
893 –    }
894 –  }
895 –
896 –  /* also send out those that are not on any channel
897 –   */
898 –  DLINK_FOREACH(ptr, global_client_list.head)
899 –  {
900 –    struct Client *target_p = ptr->data;
901 –
902 –    if (!HasFlag(target_p, FLAGS_BURSTED) && target_p->from != client_p)
903 –      sendnick_TS(client_p, target_p);
904 –
905 –    DelFlag(target_p, FLAGS_BURSTED);
906 –  }
907 –
908 –  if (IsCapable(client_p, CAP_EOB))
909 –    sendto_one(client_p, ":%s EOB", me.id);
910 – }
911 –
912 – /*
913 – * send_tb
914 – *
915 – * inputs       - pointer to Client
916 – *              - pointer to channel
917 – * output       - NONE
918 – * side effects - Called on a server burst when
919 – *                server is CAP_TBURST capable
920 – */
921 – static void
922 – send_tb(struct Client *client_p, struct Channel *chptr)
923 – {
924 –  /*
925 –   * We may also send an empty topic here, but only if topic_time isn't 0,
926 –   * i.e. if we had a topic that got unset.  This is required for syncing
927 –   * topics properly.
928 –   *
929 –   * Imagine the following scenario: Our downlink introduces a channel
930 –   * to us with a TS that is equal to ours, but the channel topic on
931 –   * their side got unset while the servers were in splitmode, which means
932 –   * their 'topic' is newer.  They simply wanted to unset it, so we have to
933 –   * deal with it in a more sophisticated fashion instead of just resetting
934 –   * it to their old topic they had before.  Read m_tburst.c:ms_tburst
935 –   * for further information   -Michael
936 –   */
937 –  if (chptr->topic_time)
938 –    sendto_one(client_p, ":%s TBURST %lu %s %lu %s :%s", me.id,
939 –               (unsigned long)chptr->channelts, chptr->chname,
940 –               (unsigned long)chptr->topic_time,
941 –               chptr->topic_info,
942 –               chptr->topic);
943 – }
944 –
945 – /* burst_members()
946 – *
947 – * inputs       - pointer to server to send members to
948 – *              - dlink_list pointer to membership list to send
949 – * output       - NONE
950 – * side effects -
951 – */
952 – static void
953 – burst_members(struct Client *client_p, struct Channel *chptr)
954 – {
955 –  struct Client *target_p;
956 –  struct Membership *ms;
957 –  dlink_node *ptr;
958 –
959 –  DLINK_FOREACH(ptr, chptr->members.head)
960 –  {
961 –    ms       = ptr->data;
962 –    target_p = ms->client_p;
963 –
964 –    if (!HasFlag(target_p, FLAGS_BURSTED))
965 –    {
966 –      AddFlag(target_p, FLAGS_BURSTED);
967 –
968 –      if (target_p->from != client_p)
969 –        sendnick_TS(client_p, target_p);
970 –    }
971 –  }
972 – }
973 –
587   /* New server connection code
588   * Based upon the stuff floating about in s_bsd.c
589   *   -- adrian
# Line 1054 | Line 667 | serv_connect(struct MaskItem *conf, stru
667    strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost));
668  
669    /* create a socket for the server connection */
670 <  if (comm_open(&client_p->localClient->fd, conf->addr.ss.ss_family,
1058 <                SOCK_STREAM, 0, NULL) < 0)
670 >  if (comm_open(&client_p->localClient->fd, conf->addr.ss.ss_family, SOCK_STREAM, 0, NULL) < 0)
671    {
672      /* Eek, failure to create the socket */
673 <    report_error(L_ALL, "opening stream socket to %s: %s",
674 <                 conf->name, errno);
673 >    report_error(L_ALL, "opening stream socket to %s: %s", conf->name, errno);
674 >
675      SetDead(client_p);
676      exit_client(client_p, "Connection failed");
677      return 0;
# Line 1099 | Line 711 | serv_connect(struct MaskItem *conf, stru
711  
712    SetConnecting(client_p);
713    dlinkAdd(client_p, &client_p->node, &global_client_list);
714 <  /* from def_fam */
714 >
715    client_p->localClient->aftype = conf->aftype;
716  
717    /* Now, initiate the connection */

Diff Legend

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