+2004-12-14 Michael Poole <mdpoole@troilus.org>
+
+ * 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 <mdpoole@troilus.org>
* doc/example.conf: Update General block comment to mention
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 */
#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. */
#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. */
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 */
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,
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));
/*
* 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" : "",
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));
}
}
}
}
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))
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.