/* This test was made to demonstrate a weakness in the horizon/blackhole protocol. (but failed to prove anything because the horizon is not "listening" to new connection until it receives something from the blackhole. It means it does not even see the early "close" of the socket). The protocol works like this client connects to the horizon: This is horizon handle 10 for example horizon identifies the client (vserver) from its IP. horizon identifies the target IP and convert that to name (normally ip0) horizon identified the target port. It sends "connect vserver ip0 port 10" to blackhole. If blackhole accept the connection, it replies on a new master connection: link 10 Now what happen if the following sequence occurs client connects to horizon on handle 10. horizon sends request to blackhole client close connection another client connects (to a different IP, port, from a different vserver) and gets also handle 10. horizon sends a new "connect" request to blackhole. But a moment later, receive the first answer from blackhole which request to "link 10". Now, the new socket will be connected to the wrong end. So we must change how the horizon send "handle" information to the blackhole so unique id are used instead of raw file handle (which are reused all the time). So this program will try to create this situation and then we will change the horizon server to fix it. No one file a bug. This just came out of a review... But this bug was impossible to trigger anyway... */ #include #include #include #include #include #include #include /* We connect and we hang up immediatly */ static void connect_hangup(const char *addr, const char *port) { (addr,port,5); end = true; } /* Now we connect and let the tcpecho process replies (so blackhole and horizon have fully completed the connection) */ static void connect_check(const char *addr, const char *port) { (addr,port,5); if (strstr(line,"9004")==NULL){ printf ("BUG Receive %d: %s\n",info.linelen,line); } end = true; } int main (int argc, char *argv[]) { glocal const char *addr = "192.168.2.1"; glocal const char *port1 = NULL; glocal const char *port2 = NULL; glocal int loop = 100; glocal int nbfork = 1; glocal bool oneproc = false; glocal bool subprocs = false; glocal int ret = -1; glocal.ret = (argc,argv); setarg ('a',"addr","ip of the horizon",glocal.addr,false); setarg (' ',"port1","First port",glocal.port1,true); setarg (' ',"port2","Second port",glocal.port2,true); setarg (' ',"loop","Second port",glocal.loop,false); setarg (' ',"nbfork","Number of process using the first port",glocal.nbfork,false); setgrouparg ("Modes"); setarg (' ',"subprocs","Use many processes hanging up",glocal.subprocs,false); setarg (' ',"oneproc","One process hangups and connects",glocal.oneproc,false); if (glocal.subprocs){ pid_t tbpid[glocal.nbfork]; for (int i=0; i return glocal.ret; }