From 8ee87dd0dddbf06fedbe255aa155da73cac60858 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Thu, 16 Dec 2004 03:28:52 +0000 Subject: [PATCH] Add new server flag (+6) to indicate IPv6 address format support. If a peer server does not advertise that flag, send 0.0.0.0 as the IP for IPv6 users. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1274 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 24 ++++++++++++++++++++++++ include/client.h | 5 +++++ include/numnicks.h | 2 +- include/send.h | 6 ++++++ ircd/s_bsd.c | 2 +- ircd/s_serv.c | 4 ++-- ircd/s_user.c | 25 ++++++++++++++++++------- ircd/send.c | 41 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 98 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index aa11bc9..b8c4394 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2004-12-14 Michael Poole + + * include/client.h (FLAG_IPV6): New value for enum Flag. + (IsIPv6, SetIPv6): Accessor macros for it. + + * include/numnicks.h (iptobase64): Add flag indicating whether to + use full IPv6 addresses or fake them in an IPv4-compatible way. + + * ircd/numnicks.c (iptobase64): Use the new flag. + + * include/send.h (sendcmdto_flag_serv_butone): New function to + send different lines to servers based on flags (like FLAG_IPV6). + + * ircd/send.c (sendcmdto_flag_serv_butone): Implement it. + + * ircd/s_bsd.c (completed_connection): Advertise IPv6 support in + our server flags. + + * ircd/s_serv.c (server_estab): Likewise. Also make sure we send + compatible IP addresses for the new server. + + * ircd/s_user.c (register_user): Only send full IPv6 addresses to + links that have FLAG_IPV6 set. + 2004-12-13 Michael Poole * doc/example.conf: Update General block comment to mention diff --git a/include/client.h b/include/client.h index d0ee127..b08f7cb 100644 --- a/include/client.h +++ b/include/client.h @@ -143,6 +143,7 @@ enum Flag FLAG_CLOSING, /**< set when closing to suppress errors */ FLAG_UPING, /**< has active UDP ping request */ FLAG_HUB, /**< server is a hub */ + FLAG_IPV6, /**< server understands P10 IPv6 addrs */ FLAG_SERVICE, /**< server is a service */ FLAG_GOTID, /**< successful ident lookup achieved */ FLAG_DOID, /**< I-lines say must use ident return */ @@ -574,6 +575,8 @@ struct Client { #define SendWallops(x) HasFlag(x, FLAG_WALLOP) /** Return non-zero if the client claims to be a hub. */ #define IsHub(x) HasFlag(x, FLAG_HUB) +/** Return non-zero if the client understands IPv6 addresses in P10. */ +#define IsIPv6(x) HasFlag(x, FLAG_IPV6) /** Return non-zero if the client claims to be a services server. */ #define IsService(x) HasFlag(x, FLAG_SERVICE) /** Return non-zero if the client has an account stamp. */ @@ -620,6 +623,8 @@ struct Client { #define SetServNotice(x) SetFlag(x, FLAG_SERVNOTICE) /** Mark a client as being a hub server. */ #define SetHub(x) SetFlag(x, FLAG_HUB) +/** Mark a client as being an IPv6-grokking server. */ +#define SetIPv6(x) SetFlag(x, FLAG_IPV6) /** Mark a client as being a services server. */ #define SetService(x) SetFlag(x, FLAG_SERVICE) /** Mark a client as having an account stamp. */ diff --git a/include/numnicks.h b/include/numnicks.h index aca184a..c6e4269 100644 --- a/include/numnicks.h +++ b/include/numnicks.h @@ -84,7 +84,7 @@ extern struct Client* FindNServer(const char* numeric); extern unsigned int base64toint(const char* str); extern const char* inttobase64(char* buf, unsigned int v, unsigned int count); -extern const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int count); +extern const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int count, int v6_ok); extern void base64toip(const char* s, struct irc_in_addr* addr); #endif /* INCLUDED_numnicks_h */ diff --git a/include/send.h b/include/send.h index b43733a..1825e4d 100644 --- a/include/send.h +++ b/include/send.h @@ -44,6 +44,12 @@ extern void sendcmdto_prio_one(struct Client *from, const char *cmd, const char *tok, struct Client *to, const char *pattern, ...); +/* Send command to servers by flags except one */ +extern void sendcmdto_flag_serv_butone(struct Client *from, const char *cmd, + const char *tok, struct Client *one, + int require, int forbid, + const char *pattern, ...); + /* Send command to all servers except one */ extern void sendcmdto_serv_butone(struct Client *from, const char *cmd, const char *tok, struct Client *one, diff --git a/ircd/s_bsd.c b/ircd/s_bsd.c index 97c63b0..47a9afd 100644 --- a/ircd/s_bsd.c +++ b/ircd/s_bsd.c @@ -384,7 +384,7 @@ static int completed_connection(struct Client* cptr) cli_lasttime(cptr) = CurrentTime; SetFlag(cptr, FLAG_PINGSENT); - sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s :%s", + sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6 :%s", cli_name(&me), cli_serv(&me)->timestamp, newts, MAJOR_PROTOCOL, NumServCap(&me), feature_bool(FEAT_HUB) ? "h" : "", cli_info(&me)); diff --git a/ircd/s_serv.c b/ircd/s_serv.c index 2fb0794..24915e9 100644 --- a/ircd/s_serv.c +++ b/ircd/s_serv.c @@ -128,7 +128,7 @@ int server_estab(struct Client *cptr, struct ConfItem *aconf) /* * Pass my info to the new server */ - sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s :%s", + sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6 :%s", cli_name(&me), cli_serv(&me)->timestamp, cli_serv(cptr)->timestamp, MAJOR_PROTOCOL, NumServCap(&me), feature_bool(FEAT_HUB) ? "h" : "", @@ -258,7 +258,7 @@ int server_estab(struct Client *cptr, struct ConfItem *aconf) cli_name(acptr), cli_hopcount(acptr) + 1, cli_lastnick(acptr), cli_user(acptr)->username, cli_user(acptr)->realhost, *s ? "+" : "", s, *s ? " " : "", - iptobase64(xxx_buf, &cli_ip(acptr), sizeof(xxx_buf)), + iptobase64(xxx_buf, &cli_ip(acptr), sizeof(xxx_buf), IsIPv6(cptr)), NumNick(acptr), cli_info(acptr)); } } diff --git a/ircd/s_user.c b/ircd/s_user.c index 3e7fd6b..958bb90 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -657,13 +657,24 @@ int register_user(struct Client *cptr, struct Client *sptr, } } tmpstr = umode_str(sptr); - sendcmdto_serv_butone(user->server, CMD_NICK, cptr, - "%s %d %Tu %s %s %s%s%s%s %s%s :%s", - nick, cli_hopcount(sptr) + 1, cli_lastnick(sptr), - user->username, user->realhost, - *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "", - iptobase64(ip_base64, &cli_ip(sptr), sizeof(ip_base64)), - NumNick(sptr), cli_info(sptr)); + /* Send full IP address to IPv6-grokking servers. */ + sendcmdto_flag_serv_butone(user->server, CMD_NICK, cptr, + FLAG_IPV6, FLAG_LAST_FLAG, + "%s %d %Tu %s %s %s%s%s%s %s%s :%s", + nick, cli_hopcount(sptr) + 1, cli_lastnick(sptr), + user->username, user->realhost, + *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "", + iptobase64(ip_base64, &cli_ip(sptr), sizeof(ip_base64), 1), + NumNick(sptr), cli_info(sptr)); + /* Send fake IPv6 addresses to pre-IPv6 servers. */ + sendcmdto_flag_serv_butone(user->server, CMD_NICK, cptr, + FLAG_LAST_FLAG, FLAG_IPV6, + "%s %d %Tu %s %s %s%s%s%s %s%s :%s", + nick, cli_hopcount(sptr) + 1, cli_lastnick(sptr), + user->username, user->realhost, + *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "", + iptobase64(ip_base64, &cli_ip(sptr), sizeof(ip_base64), 0), + NumNick(sptr), cli_info(sptr)); /* Send server notice mask to client */ if (MyUser(sptr) && (cli_snomask(sptr) != SNO_DEFAULT) && HasFlag(sptr, FLAG_SERVNOTICE)) diff --git a/ircd/send.c b/ircd/send.c index 4dc21ea..ec4d69b 100644 --- a/ircd/send.c +++ b/ircd/send.c @@ -363,6 +363,47 @@ void sendcmdto_prio_one(struct Client *from, const char *cmd, const char *tok, msgq_clean(mb); } +/** + * Send a (prefixed) command to all servers matching or not matching a + * flag but one. + * @param[in] from Client sending the command. + * @param[in] cmd Long name of command (ignored). + * @param[in] tok Short name of command. + * @param[in] one Client direction to skip (or NULL). + * @param[in] require Only send to servers with this Flag bit set. + * @param[in] forbid Do not send to servers with this Flag bit set. + * @param[in] pattern Format string for command arguments. + */ +void sendcmdto_flag_serv_butone(struct Client *from, const char *cmd, + const char *tok, struct Client *one, + int require, int forbid, + const char *pattern, ...) +{ + struct VarData vd; + struct MsgBuf *mb; + struct DLink *lp; + + vd.vd_format = pattern; /* set up the struct VarData for %v */ + va_start(vd.vd_args, pattern); + + /* use token */ + mb = msgq_make(&me, "%C %s %v", from, tok, &vd); + va_end(vd.vd_args); + + /* send it to our downlinks */ + for (lp = cli_serv(&me)->down; lp; lp = lp->next) { + if (one && lp->value.cptr == cli_from(one)) + continue; + if ((require < FLAG_LAST_FLAG) && !HasFlag(lp->value.cptr, require)) + continue; + if ((forbid < FLAG_LAST_FLAG) && HasFlag(lp->value.cptr, forbid)) + continue; + send_buffer(lp->value.cptr, mb, 0); + } + + msgq_clean(mb); +} + /** * Send a (prefixed) command to all servers but one. * @param[in] from Client sending the command. -- 2.20.1