IPv6 posting backoff patches for CURRENT snapshot
Antonio Querubin
tony at lava.net
Sat Apr 6 10:02:45 UTC 2002
Although it was known that the posting backoff routines never worked for
IPv6 clients in the CURRENT snapshot, after looking through the source I
have to wonder how it ever worked for IPv4 clients as well. Attached are
patches that hopefully make it work for both IPv4 and IPv6. The attached
patches also incorporate some other patches for nnrpd I submitted earlier
in the week but which haven't made their way into the CURRENT snapshot
yet.
Previously, the PostRecFilename() function had been called with a long int
parameter passed as the first argument which carried the IP address info.
To accomodate IPv6, this was changed to a string pointer and
PostRecFilename() is passed the IP address as a string.
For IPv4 addresses, PostRecFilename() continues to create multiple
sub-directories under which the PostRecords are stored. The algorithm
uses the first through third octets of the IPv4 address to create the
directory names while the fourth octet is the file name. This means that
at most 256 PostRecord files will be created in any one sub-directory.
This places a cap on the size of directories.
In IPv6 things are a little more complicated. A /64 prefix could contain
very few hosts if the network uses EUI-64 based addresses. Or it could
potentially contain very many hosts if the addresses statically assigned
sequentially. So how do we generate a directory name and filename for
IPv6 clients? Practical considerations do limit the number of hosts on
any subnet. But more importantly, for the next few years, I expect
users of IPv6 news clients will still be a small minority. So rather than
try to figure out how to generate a sub-directory and filename out of a
128 bit IPv6 address it seemed simpler to just use the whole IPv6 address
as the filename and forego creating sub-directories.
At some point in the future this will need to change as IPv6 news clients
become more popular. Perhaps by then someone (else :)) can convert the
routines to use a DBZ file instead of the current method of
sub-directories and individual files per IP address.
-- Attached file included as plaintext by Ecartis --
-- File: commands.c.diff
--- nnrpd/commands.c.orig Wed Apr 3 00:00:53 2002
+++ nnrpd/commands.c Thu Apr 4 01:05:23 2002
@@ -745,7 +745,7 @@
/* Acquire lock (this could be in RateLimit but that would
* invoke the spaghetti factor).
*/
- if ((path = (char *) PostRecFilename(ClientIpAddr,PERMuser)) == NULL) {
+ if ((path = (char *) PostRecFilename(ClientIpString,PERMuser)) == NULL) {
Reply("%s\r\n", NNTP_CANTPOST);
return;
}
-- Attached file included as plaintext by Ecartis --
-- File: misc.c.diff
--- nnrpd/misc.c.orig Wed Apr 3 00:00:53 2002
+++ nnrpd/misc.c Fri Apr 5 22:12:47 2002
@@ -356,13 +356,6 @@
!(PERMaccessconf->backoff_k >= 0L && PERMaccessconf->backoff_postfast >= 0L && PERMaccessconf->backoff_postslow >= 1L))
return;
-#ifdef HAVE_INET6
- /* FIXME - backoff is only disabled because I'm too lazy to figure out the
- best way to fix it for IPv6 users. -lutchann */
- syslog(L_ERROR, "%s backoff is not available with IPv6 build",ClientHost);
- return;
-#endif
-
/* Need this database for backing off */
(void)strncpy(postrec_dir,PERMaccessconf->backoff_db,SMBUF);
if (stat(postrec_dir, &st) < 0) {
@@ -394,7 +387,7 @@
*/
char
*PostRecFilename(ip,user)
- unsigned long ip;
+ char *ip;
char *user;
{
static char buff[SPOOLNAMEBUFF];
@@ -407,10 +400,19 @@
return(buff);
}
- for (i=0; i<4; i++) {
- addr[i] = (unsigned char) (0x000000ff & (ip>>(i*8)));
+ if (inet_aton(ip, dirbuff) < 1) {
+ /* If inet_aton() fails, we'll assume it's an IPv6 address. We'll
+ also assume for now that we're dealing with a limited number of
+ IPv6 clients so we'll place their files all in the same
+ directory for simplicity. Someday we'll need to change this to
+ something more scalable such as DBZ when IPv6 clients become
+ more popular. */
+ snprintf(buff, sizeof buff, "%s/%s", postrec_dir, ip);
+ return(buff);
}
+ /* If it's an IPv4 address just fall through. */
+ sscanf(ip, "%d.%d.%d.%d", addr[3], addr[2], addr[1], addr[0]);
sprintf(dirbuff,"%s/%03d%03d/%03d",postrec_dir,addr[3],addr[2],addr[1]);
if (!MakeDirectory(dirbuff,TRUE)) {
syslog(L_ERROR,"%s Unable to create postrec directories '%s': %s",
@@ -455,8 +457,8 @@
continue;
}
- /* If lockfile is older than the value of PERMaccessconf->backoff_postslow, remove it
- */
+ /* If lockfile is older than the value of
+ PERMaccessconf->backoff_postslow, remove it */
statfailed = 0;
time(&now);
if (now < st.st_ctime + PERMaccessconf->backoff_postslow) continue;
-- Attached file included as plaintext by Ecartis --
-- File: nnrpd.h.diff
--- nnrpd/nnrpd.h.orig Wed Apr 3 00:00:53 2002
+++ nnrpd/nnrpd.h Thu Apr 4 00:35:44 2002
@@ -131,8 +131,8 @@
EXTERN char ServerHost[SMBUF];
EXTERN char Username[SMBUF];
#ifdef HAVE_INET6
-EXTERN char ClientIpString[40];
-EXTERN char ServerIpString[40];
+EXTERN char ClientIpString[INET6_ADDRSTRLEN];
+EXTERN char ServerIpString[INET6_ADDRSTRLEN];
#else
EXTERN char ClientIpString[20];
EXTERN char ServerIpString[20];
@@ -195,7 +195,7 @@
extern char *Glom(char **av);
extern int Argify(char *line, char ***argvp);
extern void InitBackoffConstants(void);
-extern char *PostRecFilename(unsigned long ip, char *user);
+extern char *PostRecFilename(char *ip, char *user);
extern int LockPostRec(char *path);
extern int LockPostRec(char *path);
extern void UnlockPostRec(char *path);
More information about the inn-patches
mailing list