/* Generates configurations to test blackhole on a single workstation. It uses the loopback network to generate address for horizons and blackholes Each horizon is listening on port 9000 for connections from blackholes. Each horizon is listening on 127.0.0.N,N+1,N+2 where N is defined by horizon_baseip() Each vserver tied to an horizon is listening on IP 127.0.0.M,M+1,M+2 where M is defined by horizon_vservip() */ #include #include #include #include #include #include #include #include #include #include #include using namespace std; static int NBPORT=5; static int NBVSERV=4; static int NBPROTOCHECK=3; static bool NOCONPROXY=false; /* Return the base IP number of an horizon. This is the number N in 127.0.0.N. We allocate 20 IPs per horizon. 10 for the base IP and the IP0,..N and 10 for the vservers */ static int horizon_baseip (int no_horizon) { return no_horizon*20+10; } static int horizon_vservip (int no_horizon) { return no_horizon*20+20; } static bool horizon_unixsock = false; // Use a unix socket to reach the horizon static void genconfigs (int nbhorizons, int nbblackholes) { glocal const char *user = getenv ("USER"); glocal int nbh = nbhorizons; glocal int nbb = nbblackholes; mkdir ("/tmp/tmp",0755); mkdir ("/tmp/tmp/errors",0755); mkdir ("/tmp/tmp/sock",0755); mkdir ("/tmp/tmp/pid",0755); mkdir ("/tmp/tmp/debug",0755); for (int i=0; i(f.c_str(),false); int baseip = horizon_baseip(glocal.basei); fprintf (fout,"./horizon "); for (int i=0; i chmod (f.c_str(),0755); f = string_f ("/tmp/tmp/horizon-%d-rules.sh",i); (f.c_str(),false); int baseip = horizon_vservip(glocal.basei); fprintf (fout,"./horizon-control -p /tmp/tmp/sock/horizon-%d.sock allow 127.0.0.1\n",glocal.basei); string hctl = string_f("./horizon-control -p /tmp/tmp/sock/horizon-%d.sock",glocal.basei); const char *hctl_str = hctl.c_str(); for (int i=0; i chmod (f.c_str(),0755); } ("/tmp/tmp/tcpecho.sh",false); for (int i=0; i chmod ("/tmp/tmp/tcpecho.sh",0755); for (int i=0; i(f.c_str(),false); fprintf (fout,"./blackhole --daemon --user %s --horizon_port 9000" " --control /tmp/tmp/sock/blackhole-%d.sock --statfile /tmp/blackhole-%d-connect.log" " --pidfile /tmp/tmp/pid/blackhole-%d.pid --conproxyport /tmp/tmp/sock/conproxy.sock" " --debug --debugfile /tmp/tmp/debug/blackhole-debug-%d.log --errorfile /tmp/tmp/errors/blackhole-error-%d.log\n" ,glocal.user,glocal.basei,glocal.basei,glocal.basei,glocal.basei,glocal.basei); return 0; chmod (f.c_str(),0755); f = string_f ("/tmp/tmp/blackhole-%d-rules.sh",i); (f.c_str(),false); string bkc = string_f("./blackhole-control -p /tmp/tmp/sock/blackhole-%d.sock",glocal.basei); for (int i=0; i server1 vserverN portM // and server1 vserverN portM -> server1 vserverN portM for (int i=0; i server0 const char *prefix = ""; for (int i=0; i chmod (f.c_str(),0755); } ("/tmp/tmp/2factors.sh",false); for (int i=0; i chmod ("/tmp/tmp/2factors.sh",0755); ("/tmp/tmp/http_check.conf",false); fprintf (fout,"# This is a test\n"); fprintf (fout,"GETURL=/somepage/\n"); return 0; ("/tmp/tmp/2factors-command.sh",false); fprintf (fout,"#!/bin/sh\n"); fprintf (fout,"echo `date` $* >>/tmp/2factors.log\n"); return 0; chmod ("/tmp/tmp/2factors-command.sh",0755); ("/tmp/tmp/2factors-confirm.sh",false); char path[1000]; getcwd(path,sizeof(path)); fprintf (fout,"#!/bin/sh\n"); fprintf (fout,"if [ \"$2\" = \"\" ] ; then\n"); fprintf (fout,"\t%s/protocheck-2factors-control -p /tmp/tmp/sock/protocheck-2factors-$1.sock status\\\n",path); fprintf (fout,"\t\t| grep client | while read a b c d e\n"); fprintf (fout,"\tdo\n"); fprintf (fout,"\t\techo -n \"Confirm $d: \"\n"); fprintf (fout,"\t\t%s/protocheck-2factors-control -p /tmp/tmp/sock/protocheck-2factors-$1.sock confirm $d\n",path); fprintf (fout,"\tdone\n"); fprintf (fout,"else\n"); fprintf (fout,"\t%s/protocheck-2factors-control -p /tmp/tmp/sock/protocheck-2factors-$1.sock confirm $2\n",path); fprintf (fout,"fi\n"); return 0; chmod ("/tmp/tmp/2factors-confirm.sh",0755); ("/tmp/tmp/2factors-lock.sh",false); char path[1000]; getcwd(path,sizeof(path)); fprintf (fout,"#!/bin/sh\n"); fprintf (fout,"%s/protocheck-2factors-control -p /tmp/tmp/sock/protocheck-2factors-2.sock status\\\n",path); fprintf (fout,"\t| grep client | while read a b c d e\n"); fprintf (fout,"do\n"); fprintf (fout,"\techo -n \"Lock $c: \"\n"); fprintf (fout,"\t%s/protocheck-2factors-control -p /tmp/tmp/sock/protocheck-2factors-2.sock lock $c\n",path); fprintf (fout,"done\n"); return 0; chmod ("/tmp/tmp/2factors-lock.sh",0755); if (!NOCONPROXY){ ("/tmp/tmp/conproxy.sh",false); fprintf (fout,"#!/bin/sh\n"); fprintf (fout,"./conproxy -p /tmp/tmp/sock/conproxy.sock --pidfile /tmp/tmp/pid/conproxy.pid" " --user %s --daemon --statfile /tmp/conproxy-connect.log" " --debug --debugfile /tmp/tmp/debug/conproxy.log --errorfile /tmp/tmp/errors/conproxy-error.log\n" ,glocal.user); return 0; chmod ("/tmp/tmp/conproxy.sh",0755); } ("/tmp/tmp/stopall",false); for (int i=0; i chmod ("/tmp/tmp/stopall",0755); ("/tmp/tmp/startall",false); for (int i=0; i chmod ("/tmp/tmp/startall",0755); ("/tmp/tmp/status",false); fprintf (fout,"if [ \"$1\" = \"\" -o \"$1\" = \"horizon\" ]; then\n"); for (int i=0; i chmod ("/tmp/tmp/status",0755); } static int probe ( const string &bind, const string &host, // IP number of the horizon const string &port, const char *expect, unsigned nbechoreq) { glocal int ret = -1; glocal int noline = 0; glocal const char *expect = expect; glocal unsigned nbechoreq = nbechoreq; debug_printf ("probe: bind %s host %s port %s\n" ,bind.c_str(),host.c_str(),port.c_str()); (bind.c_str(),host.c_str(),port.c_str(),5); settcpnodelay(true); debug_printf ("probe len=%zu/%zu line=%s\n",strlen(glocal.expect),strlen(line),line); if (glocal.noline == 0){ if (strcmp(line,glocal.expect)==0){ glocal.ret = 0; if (glocal.nbechoreq==0){ end = true; }else{ send ("Hello\n"); } }else{ end = true; } }else{ if (strcmp(line,"echo Hello\r")!=0){ glocal.ret = -1; end = true; } glocal.nbechoreq--; if (glocal.nbechoreq == 0){ end = true; }else{ send ("Hello\n"); } } glocal.noline++; debug_printf ("probe ret=%d\n",glocal.ret); if (glocal.ret == -1){ fprintf (stderr,"probe fail bind=%s host=%s port=%s <> %s\n" ,bind.c_str(),host.c_str(),port.c_str(),expect); } return glocal.ret; } static int probe ( int fromvserver, // This is just the last number of the IP 127.0.0 // From this, we know the horizon address int ipn, // IP number of the horizon int portnum, const char *expect, unsigned nbechoreq) { string bind = string_f("127.0.0.%d",fromvserver); string host = string_f("127.0.0.%d",((fromvserver/10)-1)*10+ipn); string port = string_f("%d",portnum+9001); return probe (bind,host,port,expect,nbechoreq); } static void runtest (int nbhorizons, int nbblackholes, unsigned nbechoreq) { string msg; for (int i=0; i("127.0.0.1","22",5); glocal.sshmsg = line; end = true; for (int j=0; j int main (int argc, char *argv[]) { glocal int ret = -1; glocal int nbhorizons = 4; glocal int nbblackholes = 1; glocal int count = 1; glocal int fromvserver = 40; glocal int ipnum = 0; glocal int portnum = 0; glocal bool direct = false; glocal unsigned nbechoreq = 1; glocal int nbproc = 1; glocal.ret = (argc,argv); setproginfo ("testconfig",VERSION ,"Generates test configurations for the blackhole system\n" "Executes test sequences on these configuration.\n" "\n" "commands are:\n" "\tgen\n" "\ttest\n" "\ttestconnect\n" "\tcompare\n"); setgrouparg ("Parameters"); setarg ('b',"nbblackholes","Number of blackhole servers",glocal.nbblackholes,false); setarg ('h',"nbhorizons","Number of horizons servers",glocal.nbhorizons,false); setarg (' ',"nbport","Number of server ports (9001,...)",NBPORT,false); setarg (' ',"nbvserv","Number of vserver per horizon",NBVSERV,false); setarg (' ',"nbprotocheck","Number of protocheck services",NBPROTOCHECK,false); setarg (' ',"noconproxy","Do not use conproxy",NOCONPROXY,false); setarg (' ',"horizon_unixsock","Connects to horizon using unix socket",horizon_unixsock,false); setgrouparg ("testconnect parms"); setarg (' ',"count","Number of repetition",glocal.count,false); setarg (' ',"fromvserver","20 40 60",glocal.fromvserver,false); setarg (' ',"ipnum","0,1,2,4 horizon ip",glocal.ipnum,false); setarg (' ',"portnum","0,1,2... echo server port",glocal.portnum,false); setarg (' ',"direct","Test directly to tcpecho, without blackhole",glocal.direct,false); setarg (' ',"nbechoreq","Number of echo request after connection",glocal.nbechoreq,false); setarg (' ',"nbproc","Number of processes",glocal.nbproc,false); int ret = -1; if (argc != 1){ usage(); }else if (strcmp(argv[0],"gen")==0){ genconfigs (glocal.nbhorizons,glocal.nbblackholes); ret = 0; }else if (strcmp(argv[0],"test")==0){ runtest (glocal.nbhorizons,glocal.nbblackholes,glocal.nbechoreq); ret = 0; }else if (strcmp(argv[0],"testconnect")==0){ // This test is used to show how many connection we can do using blackhole or directly // Connections all succeed with the tcpecho server and response validation is done printf ("count=%d nbproc=%d fromvserver=%d ipnum=%d portnum=%d\n" ,glocal.count,glocal.nbproc,glocal.fromvserver,glocal.ipnum,glocal.portnum); int tovserver = glocal.fromvserver; if (glocal.fromvserver == 20) tovserver = 40; string msg = string_f ("Welcome to service echo 127.0.0.%d %d\r",tovserver,9001+glocal.portnum); string bind = "127.0.0.20"; string host = "127.0.0.21"; string port = "9001"; if (glocal.direct) msg = "Welcome to service echo 127.0.0.21 9001\r"; for (int p=0; p(bind,host,port,1); //tlmp_error ("Should not connect\n"); //end = true; tlmp_error ("Receiving something: %s\n",line); end = true; } _exit (0); }else if (pid == (pid_t)-1){ tlmp_error ("Can't fork (%s)\n",strerror(errno)); exit (-1); } } int st; while (wait(&st)!=-1); ret = 0; }else{ tlmp_error ("Invalid command: %s\n",argv[0]); usage(); } return ret; return glocal.ret; }