Henning Brauer:
> On Wed, May 29, 2002 at 07:57:27AM +0200, Lars Kristian Roland wrote:
> > I find the smtp-after-pop version included in qmail-ldap unstable.
>
> hmm, I have the opposite experience. rock-solid here with a large user base.
I think it is stable too and I have a suggestion about the usage of
pbs{add,dbd} under the high mail trafiic.
Assumption:
- very large number of users. over ten thousands.
- large mail traffic. rate of accepting smtp sessions are over 10/sec
and over 20/sec for pop sessions. the number of pop sessions is
larger than smtp.
- several servers for smtp service(accept smtp only). and pop servers
too. under the load balancer, such as UltraMonkey.
UM as LB --+-- smtp server1 (accept smtp only)
+-- smtp server2
+-- smtp serverN
+-- pop server1 (accept pop only)
+-- pop server2
+-- pop serverM
- pbsdbd must always exists over one instance, not to stop the smtp
service.
- pbs tools send and receive via udp. udp is simple and fast, but less
reliability.
Where is the best place/server I execute the pbsdbd?
a. on the smtp server1 and 2.
all pop servers pbsadd to both the smtp server1 and 2. all smtp
servers pbscheck to them. heavy traffic goes to smtp server1 and
2. the network increases twice the pop sessions, plus about the
number of smtp sessions.
(the number of pop sessions) x 2 + (the number of smtp sessions).
b. on each pop server individually.
each pop server has pbsdb and pbsadd to herself only. does not
throw the data outside of her. all smtp servers pbscheck to the
pop servers. the average number of pbscheck for a single smtp
session will be half of the number of pop servers. the network
traffic will increase
(the number of smtp session) x (the number of pop servers) / 2.
under the environment of lower traffics and the less servers, there
will be no problems. but i am wondering about the environment under
very high traffics and many servers. the pbs data passed between the
smtp and pop servers will cause a problem, such as a lost of udp
packet and involves pbscheck again and again.
Suggestion:
I have designed another usage of pbs tools and modified the source
code.
- as the method b.(written above), all the pop servers have pbs data
which she accepted and dont pbsadd to other servers.
- and also all the smtp servers runs pbsdb too. after getting the
right answer of pbscheck from one of the pop servers, he pbsadd his
own pbsdb with the original pop'ed time.
- smtp server pbscheck his own obsdb first, if it fails then to the
pop servers as the usual way.
- setting the load balancer trying re-connect the new session to the
ex-connected smtp server with the same source ip address.
and here is the patch. this is very simple and easy.
this patch changes,
pbsadd:
sets the special environtment variable, currently named
"TheTime", automaticaly, if this feature is specified.
pbsdbd:
if the $TheTime is set, replace the timeout value in pbs data
cache with it.
to use this patch, insert "TheTime" at the top of control/pbsenv.
if you dont like the variable name, modify the file pbsdb.h and
recompile them.
any comments are welcome.
i hope this patch will improve the performance of pretty pbs tools.
thank you.
Junjiro Okajima
----------------------------------------------------------------------
diff -Nu /usr/src/jro/qmail-ldap-1.03-20020501a/pbsdbd.c ./pbsdbd.c
--- /usr/src/jro/qmail-ldap-1.03-20020501a/pbsdbd.c Mon Jun 3 19:18:08 2002
+++ ./pbsdbd.c Sat Jun 29 20:02:47 2002
@@ -13,6 +13,10 @@
#include "strerr.h"
#include "substdio.h"
#include "uint32.h"
+#include "str.h"
+#include "scan.h"
+#include "pbsdb.h"
+#include "fmt.h"
struct ip_address ip;
unsigned int port = 2821;
@@ -185,6 +189,20 @@
if (pos)
set4(pos,get4(pos) ^ keyhash ^ writer);
set4(writer,pos ^ keyhash);
+ if (!str_diffn(env+2, TheTime"=", TheTimeLen+1)) {
+ char *p = env+2+TheTimeLen+1;
+ char c = *p;
+ if (c) {
+ if (c == 'x' || c == '\n') {
+ char a[8]; // unsigned long in hexdecimal string.
+ int l = fmt_xlong(a, timenow);
+ int n = 8-l;
+ while (n-- > 0) *p++ = '0';
+ byte_copy(p, l, a);
+ } else
+ scan_xlong(p, &timenow);
+ }
+ }
set4(writer + 4,timenow + timeout);
set4(writer + 8,envlen);
if (writer + 13 > cachesize ) cache_impossible();
diff -Nu /usr/src/jro/qmail-ldap-1.03-20020501a/pbsadd.c ./pbsadd.c
--- /usr/src/jro/qmail-ldap-1.03-20020501a/pbsadd.c Mon Jun 3 19:18:08 2002
+++ ./pbsadd.c Sat Jun 29 18:19:07 2002
@@ -14,6 +14,8 @@
#include "readwrite.h"
#include "stralloc.h"
#include "substdio.h"
+#include "str.h"
+#include "pbsdb.h"
static void die() { _exit(1); }
@@ -144,6 +146,12 @@
*buf++ = numenvs; len++;
e = envs.s;
+ if (str_equal(e, TheTime)) {
+ v = env_get(e);
+ // unsigned long in hex, to reserve my room.
+ if (!v) env_put2(TheTime, "xxxxxxxx");
+ }
+
for(i=0; i < numenvs; i++) {
v = env_get(e);
elen = str_len(e);
diff -Nu /usr/src/jro/qmail-ldap-1.03-20020501a/pbsdb.h ./pbsdb.h
--- /usr/src/jro/qmail-ldap-1.03-20020501a/pbsdb.h Thu Jan 1 09:00:00 1970
+++ ./pbsdb.h Sat Jun 29 14:44:21 2002
@@ -0,0 +1,7 @@
+#ifndef __PBSDB_H__
+#define __PBSDB_H__
+
+#define TheTime "TheTime"
+#define TheTimeLen 7
+
+#endif
diff -Nu /usr/src/jro/qmail-ldap-1.03-20020501a/fmt_xlong.c ./fmt_xlong.c
--- /usr/src/jro/qmail-ldap-1.03-20020501a/fmt_xlong.c Thu Jan 1 09:00:00 1970
+++ ./fmt_xlong.c Sat Jun 29 15:35:30 2002
@@ -0,0 +1,14 @@
+#include "fmt.h"
+
+unsigned int fmt_xlong(s,u) register char *s; register unsigned long u;
+{
+ register unsigned int len; register unsigned long q;
+ char a[] = "0123456789ABCDEF";
+ len = 1; q = u;
+ while (q > 15) { ++len; q /= 16; }
+ if (s) {
+ s += len;
+ do { *--s = a[u % 16]; u /= 16; } while(u); /* handles u == 0 */
+ }
+ return len;
+}
diff -Nu /usr/src/jro/qmail-ldap-1.03-20020501a/scan_xlong.c ./scan_xlong.c
--- /usr/src/jro/qmail-ldap-1.03-20020501a/scan_xlong.c Thu Jan 1 09:00:00 1970
+++ ./scan_xlong.c Sat Jun 29 17:30:05 2002
@@ -0,0 +1,23 @@
+#include "scan.h"
+
+//static inline
+unsigned long f(unsigned char c)
+{
+ if (c < '9')
+ c -= '0';
+ else {
+ if (c > 'a') c -= 'a'-'A';
+ c -= 'A'-10;
+ }
+ return c;
+}
+
+unsigned int scan_xlong(s,u) register char *s; register unsigned long *u;
+{
+ register unsigned int pos; register unsigned long result;
+ register unsigned long c;
+ pos = 0; result = 0;
+ while ((c = f(s[pos])) < 16)
+ { result = result * 16 + c; ++pos; }
+ *u = result; return pos;
+}
diff -Nu /usr/src/jro/qmail-ldap-1.03-20020501a/Makefile ./Makefile
--- /usr/src/jro/qmail-ldap-1.03-20020501a/Makefile Mon Jun 3 20:05:34 2002
+++ ./Makefile Sat Jun 29 15:37:28 2002
@@ -745,6 +745,10 @@
compile fmt_ulong.c fmt.h
./compile fmt_ulong.c
+fmt_xlong.o: \
+compile fmt_xlong.c fmt.h
+ ./compile fmt_xlong.c
+
fmtqfn.o: \
compile fmtqfn.c fmtqfn.h fmt.h auto_split.h
./compile fmtqfn.c
@@ -1199,10 +1203,10 @@
pbsdbd: \
load pbsdbd.o control.o now.o ip.o ndelay.a getln.a open.a stralloc.a \
-alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o socket.lib
+alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o socket.lib fmt_xlong.o
+scan_xlong.o
./load pbsdbd control.o now.o ip.o ndelay.a getln.a open.a \
stralloc.a alloc.a strerr.a substdio.a error.a str.a fs.a \
- auto_qmail.o `cat socket.lib`
+ auto_qmail.o `cat socket.lib` fmt_xlong.o scan_xlong.o
pbsdbd.o: \
compile pbsdbd.c alloc.h auto_qmail.h byte.h control.h ip.h ndelay.h \
@@ -2017,6 +2021,10 @@
scan_ulong.o: \
compile scan_ulong.c scan.h
./compile scan_ulong.c
+
+scan_xlong.o: \
+compile scan_xlong.c scan.h
+ ./compile scan_xlong.c
seek.a: \
makelib seek_cur.o seek_end.o seek_set.o seek_trunc.o
----------------------------------------------------------------------