PageRenderTime 25ms CodeModel.GetById 16ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/udptest.cpp

https://github.com/gigablast/open-source-search-engine
C++ | 165 lines | 110 code | 21 blank | 34 comment | 22 complexity | 7a3cf6b9b47861a7ecb417305a5f9d24 MD5 | raw file
Possible License(s): Apache-2.0
  1// Matt Wells, copyright Sep 2001
  2
  3#include "gb-include.h"
  4
  5#include "Mem.h"
  6#include "Conf.h"
  7#include "Hostdb.h"
  8#include "UdpServer.h"
  9#include "Loop.h"
 10#include "ip.h"
 11#include <ctype.h>
 12#include "Spider.h"
 13
 14// the default protocol
 15UdpProtocol g_dp;
 16
 17// the request handler
 18static void handleRequest ( UdpSlot *slot  , int32_t     niceness ) ;
 19static void gotit         ( void    *state , UdpSlot *slot     ) ;
 20
 21// where we store the file contents, if any
 22char s_buf [ 1024*1024 ];
 23int32_t s_n = 0;
 24
 25int64_t s_startTime;
 26
 27bool mainShutdown ( bool urgent ) { return true; }
 28
 29int main ( int argc , char *argv[] ) {
 30
 31	// ip/port to ask for the file from
 32	int32_t           ip   = 0;
 33	uint16_t port = 0;
 34
 35	// . filename may be supplied 
 36	// . if so we send that file back to all who ask
 37	if ( argc == 2 && !isdigit(argv[1][0]) ) {
 38		char *fn = argv[1];
 39		log("Reading filename = %s", fn );
 40		int fd = open ( fn , O_RDONLY );
 41		if ( fd < 0 ) {
 42			log("File %s does not exist. exiting.",fn );
 43			return -1;
 44		}
 45		s_n = 0;
 46		while ( s_n < 1024*1024 && read ( fd , &s_buf[s_n] , 1 ) == 1)
 47			s_n++;
 48		close ( fd );
 49		// listen on udp port 2000
 50		port = 2000;
 51		//log("Listening on udp port %hu", port );
 52	}
 53	// otherwise if argc is 2 we ask an ip/port for the file
 54	else if ( argc == 2 && isdigit(argv[1][0]) ) {
 55		// send on udp port 2001
 56		port = 2001;
 57		ip   = atoip ( argv[1] , gbstrlen(argv[1]) );
 58	}
 59	// otherwise, print usage
 60	else {
 61		fprintf(stderr,
 62			"udptest <filename>\n"
 63			"\tThis will set up a server on udp port 2000 which\n"
 64			"\twill serve the specified filename to all incoming\n"
 65			"\trequests. The first char of the filename must NOT\n"
 66			"\tbe a number.\n\n"
 67			"udptest <ip>\n"
 68			"\tThis will send a request for a file to the\n"
 69			"\tudptest running on the specified ip. ip must be\n"
 70			"\tof form like 1.2.3.4\n"
 71			"\tIt will listen on udp port 2001.\n"
 72			);
 73		return -1;
 74	}
 75		// init our table for doing zobrist hashing
 76	if ( ! hashinit() ) {
 77		log("main::hashinit failed" ); return 1; }
 78		// default conf filename
 79	char *confFilename = "./gigablast.conf";
 80	if ( ! g_conf.init ( confFilename ) ) {
 81		fprintf (stderr,"main::Conf init failed\n" ); return 1; }
 82	// init the memory class after conf since it gets maxMem from Conf
 83 	if ( ! g_mem.init ( 1000000000 ) ) {
 84		fprintf (stderr,"main::Mem init failed" ); return 1; }
 85		// start up hostdb
 86	if ( ! g_hostdb.init()     ) {
 87		log("main::Hostdb init failed" ); return 1; }
 88		
 89	// init the loop
 90	if ( ! g_loop.init() ) {
 91		fprintf ( stderr , "main::Loop init failed\n" ); 
 92		return 1; 
 93	}
 94
 95	// . then our main udp server
 96	// . must pass defaults since g_dns uses it's own port/instance of it
 97	// . server should listen to a socket and register with g_loop
 98	// . the last 1 and 0 are respective niceness levels
 99	if ( ! g_udpServer.init( port                 , // use 2000 or 2001
100				 &g_dp                , // use default proto
101				 0                    , // niceness = 0
102				 1024*1024              ,
103				 1024*1024              )){
104		fprintf ( stderr, "main::UdpServer init failed\n"); 
105		return 1; 
106	}
107
108	// . otherwise, set up a handler for incoming msgTypes of 0x00
109	// . register a handler for msgType 0x00
110	// . we must register this msgType even if we're not going to handle
111	//   these requests, because we may send them...
112	if ( ! g_udpServer.registerHandler ( 0x00 , handleRequest )) {
113		fprintf ( stderr , "udp server registration failed\n");
114		return 1;
115	}
116
117	// if ip is non-zero send a request to it
118	if ( ip != 0 ) {
119		log("Sending request to ip=%s port=2000", argv[1] );
120		s_startTime = gettimeofdayInMilliseconds();
121		g_udpServer.sendRequest ( NULL , // msg ptr
122					  0    , // msg size
123					  0x00 , // msg type
124					  ip   , // ip 
125					  2000 , // port
126					  0    , // hostId (bogus)
127					  NULL , // UdpSlot ptr being used
128					  NULL , // callback state
129					  gotit, // callback
130					  30   );// timeout in seconds
131	}
132
133	// . now start g_loops main interrupt handling loop
134	// . it should block forever
135	// . when it gets a signal it dispatches to a server or db to handle it
136	if ( ! g_loop.runLoop()    ) {
137		log("main::runLoop failed" ); 
138		return 1; 
139	}
140
141	// dummy return (0-->normal exit status for the shell)
142	return 0;
143}
144
145
146void handleRequest ( UdpSlot *slot , int32_t niceness ) {
147
148	log("got request of type 0x00");
149
150	// send the deisignated file back
151	g_udpServer.sendReply ( s_buf ,  // data ptr
152				s_n   ,  // data size
153				0     ,  // allocated size
154				slot  );
155	//sendErrorReply ( slot , EBADREQUESTSIZE )
156}
157
158void gotit ( void *state , UdpSlot *slot ) {
159	// compute speed
160	double size    = slot->m_readBufSize;
161	double elapsed = gettimeofdayInMilliseconds() - s_startTime;
162	log("got reply. %f Mbps", (size*8/(1024.0*1024.0)) / (elapsed / 1000.0) );
163	// exit for good
164	exit(-1);
165}