test_peer.cc

来自「BCAST Implementation for NS2」· CC 代码 · 共 850 行 · 第 1/2 页

CC
850
字号
	printf("Sending: %s", bgppp(buf, len).c_str());    return true;}voidTestPeer::send_complete(AsyncFileWriter::Event ev, const uint8_t *buf,			const size_t buf_bytes, const size_t offset){    switch(ev) {    case AsyncFileOperator::DATA:	debug_msg("event: data\n");	if (offset == buf_bytes)	    delete[] buf;	break;    case AsyncFileOperator::FLUSHING:	debug_msg("event: flushing\n");	debug_msg("Freeing Buffer for sent packet: %x\n", (uint)buf);	delete[] buf;	break;    case AsyncFileOperator::ERROR_CHECK_ERRNO:	debug_msg("event: error\n");	/* Don't free the message here we'll get it in the flush */	XLOG_ERROR("Writing buffer failed: %s",  strerror(errno));    case AsyncFileOperator::END_OF_FILE:	XLOG_ERROR("End of File: %s",  strerror(errno));    }}boolTestPeer::zap(int& fd, const char *msg){    debug_msg("%s = %d\n", msg, fd);    if(UNCONNECTED == fd)	return true;    int tempfd = fd;    fd = UNCONNECTED;   _eventloop.remove_selector(tempfd);   debug_msg("Removing selector for fd = %d\n", tempfd);   if(-1 == ::close(tempfd)) {	XLOG_WARNING("Close of %s failed %s", msg, strerror(errno));	return false;   }   return true;;}boolTestPeer::disconnect(string& error_string){    debug_msg("\n");    if(UNCONNECTED == _s) {	XLOG_WARNING("Not connected");	error_string = "Not connected";	return false;    }    delete _async_writer;    _async_writer = 0;    return ZAP(_s);}voidTestPeer::reset(){    debug_msg("\n");    delete _async_writer;    _async_writer = 0;    ZAP(_s);    ZAP(_listen);}boolTestPeer::terminate(string& /*error_string*/){    debug_msg("\n");    _done = true;    return true;}/*** Process incoming connection attempts.*/voidTestPeer::connect_attempt(int fd, SelectorMask m){    debug_msg("\n");    if(SEL_RD != m) {	XLOG_WARNING("Unexpected SelectorMask %#x", m);	return;    }    if(UNCONNECTED != _s) {	XLOG_WARNING("Connection attempt while already connected");	return;    }    XLOG_ASSERT(_listen == fd);    _listen = UNCONNECTED;    struct sockaddr_in cliaddr;    socklen_t clilen = sizeof(cliaddr);    int connfd = accept(fd, reinterpret_cast<struct sockaddr *>(&cliaddr),			&clilen);    debug_msg("Incoming connection attempt %d\n", connfd);    /*    ** We don't want any more connection attempts so remove ourselves    ** from the eventloop and close the file descriptor.    */   _eventloop.remove_selector(fd);   debug_msg("Removing selector for fd = %d\n", fd);   if(-1 == ::close(fd))	XLOG_WARNING("Close failed");   /*   ** If there is a coordinator then add a selector.   */   if(0 != _coordinator.length() &&       !_eventloop.add_selector(connfd, SEL_RD,				callback(this, &TestPeer::receive))) {	::close(connfd);	XLOG_WARNING("Failed to add socket %d to eventloop", connfd);	return;    }   /*   ** Set up the async writer.   */    if(fcntl(connfd, F_SETFL, O_NONBLOCK) < 0) {        XLOG_FATAL("Failed to go non-blocking: %s", strerror(errno));    }    delete _async_writer;   _async_writer = new AsyncFileWriter(_eventloop, connfd);   _s = connfd;}/*** Process incoming bytes*/voidTestPeer::receive(int fd, SelectorMask m){    debug_msg("\n");    if(SEL_RD != m) {	XLOG_WARNING("Unexpected SelectorMask %#x", m);	return;    }    if(0 == _coordinator.length()) {	XLOG_WARNING("No coordinator configured");	return;    }    /*    ** If requested perform BGP packetisation.    */    int len;    if(!_bgp) {	uint8_t buf[64000];	if(-1 == (len = read(fd, buf, sizeof(buf)))) {	    string error = c_format("read error: %s", strerror(errno));	    XLOG_WARNING(error.c_str());	    datain(ERROR, _bgp_buf, _bgp_bytes, error);	    return;	}	datain(GOOD, _bgp_buf, _bgp_bytes);	return;    }    /*    ** Now doing BGP packetisation.    */    int get;    if(_bgp_bytes < BGP_COMMON_HEADER_LEN) {	get = BGP_COMMON_HEADER_LEN - _bgp_bytes;    } else {	const fixed_header *header =	    reinterpret_cast<const struct fixed_header *>(_bgp_buf);	u_short length = ntohs(header->length);	get = length - _bgp_bytes;    }    if(-1 == (len = read(fd, &_bgp_buf[_bgp_bytes], get))) {	string error = c_format("read error: %s", strerror(errno));	XLOG_WARNING(error.c_str());	datain(ERROR, _bgp_buf, _bgp_bytes, error);	_bgp_bytes = 0;	::close(fd);	_s = UNCONNECTED;	_eventloop.remove_selector(fd);	return;    }    if(0 == len) {	if(0 < _bgp_bytes)	    datain(GOOD, _bgp_buf, _bgp_bytes);	datain(CLOSED, 0, 0);	_bgp_bytes = 0;	::close(fd);	_s = UNCONNECTED;	_eventloop.remove_selector(fd);	return;    }    _bgp_bytes += len;    if(_bgp_bytes >= BGP_COMMON_HEADER_LEN) {	const fixed_header *header =	    reinterpret_cast<const struct fixed_header *>(_bgp_buf);	u_short length = ntohs(header->length);	if(length < MINPACKETSIZE || length > sizeof(_bgp_buf)) {	    string error = c_format("Illegal length value %d", length);	    XLOG_ERROR(error.c_str());	    datain(ERROR, _bgp_buf, _bgp_bytes, error);	    _bgp_bytes = 0;	    return;	}	if(length == _bgp_bytes) {	    datain(GOOD, _bgp_buf, _bgp_bytes);	    _bgp_bytes = 0;	}    }}/*** Send data received on the socket back to the coordinator*/voidTestPeer::datain(status st, uint8_t *ptr, size_t len, string error){    debug_msg("status = %d len = %u error = %s\n", st, (uint32_t)len,	      error.c_str());    if(_verbose) {	switch(st) {	case GOOD:	    if(_bgp)		printf("Received: %s", bgppp(ptr, len).c_str());	    break;	case CLOSED:	    printf("Connection closed by peer\n");	    break;	case ERROR:	    printf("Error on connection\n");	    break;	}    }    queue_data(st, ptr, len, error);}/*** It is possible to overrun the XRL code by sending too many** XRL's. Therefore queue the data that needs to be sent and only have** a small number of outstanding XRL's at any time.*/voidTestPeer::queue_data(status st, uint8_t *ptr, size_t len, string error){    Queued q;    TimeVal tv;    _eventloop.current_time(tv);    q.secs = tv.sec();    q.micro = tv.usec();    q.st = st;    q.len = len;    for(size_t i = 0; i < len; i++)	q.v.push_back(ptr[i]);    q.error = error;    _xrl_queue.push(q);    sendit();}/*** If there is any queued data and less than the allowed quota is in** flight send some more.*/voidTestPeer::sendit(){    if(_flying >= FLYING_LIMIT)	return;    if(_xrl_queue.empty())	return;    Queued q = _xrl_queue.front();    _xrl_queue.pop();    XrlDatainV0p1Client datain(&_xrlrouter);    debug_msg("%u\n", (uint32_t)q.v.size());    XLOG_ASSERT(q.len == q.v.size());    _flying++;    switch(q.len) {    case 0:	datain.send_closed(_coordinator.c_str(), _server, _genid,			   callback(this, &TestPeer::xrl_callback));	break;    case -1:	datain.send_error(_coordinator.c_str(), _server, _genid, q.error,			  callback(this, &TestPeer::xrl_callback));	break;    default:	datain.send_receive(_coordinator.c_str(), _server, _genid,			    GOOD == q.st ? true : false,			    q.secs, q.micro,			    q.v,			    callback(this, &TestPeer::xrl_callback));	break;    }}voidTestPeer::xrl_callback(const XrlError& error){    debug_msg("callback %s\n", error.str().c_str());    if(XrlError::OKAY() != error) {	if(XrlError::REPLY_TIMED_OUT() == error)	    XLOG_ERROR("%s: Try reducing FLYING_LIMIT",  error.str().c_str());	XLOG_ERROR("%s",  error.str().c_str());    }    _flying--;    XLOG_ASSERT(_flying >= 0);    sendit();}voidusage(char *name){    fprintf(stderr,	    "usage: %s [-h (finder host)] [-s server name] [-v][-t]\n", name);    exit(-1);}intmain(int argc, char **argv){    XorpUnexpectedHandler x(xorp_unexpected_handler);    //    // Initialize and start xlog    //    xlog_init(argv[0], NULL);    xlog_set_verbose(XLOG_VERBOSE_HIGH);    // XXX: verbosity of the error messages temporary increased    xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH);    xlog_add_default_output();    xlog_start();    int c;    const char *finder_host = "localhost";    const char *server = SERVER;    bool verbose = false;    bool trace = false;    while((c = getopt (argc, argv, "h:s:vt")) != EOF) {	switch(c) {	case 'h':	    finder_host = optarg;	    break;	case 's':	    server = optarg;	    break;	case 'v':	    verbose = true;	    break;	case 't':	    trace = true;	    break;	case '?':	    usage(argv[0]);	}    }    try {	EventLoop eventloop;	XrlStdRouter router(eventloop, server, finder_host);	TestPeer test_peer(eventloop, router, server, verbose);	XrlTestPeerTarget xrl_target(&router, test_peer, trace);	bool timed_out = false;	XorpTimer t = eventloop.set_flag_after_ms(10000, &timed_out);	while (router.ready() == false && timed_out == false) {	    eventloop.run();	}	if (router.ready() == false) {	    XLOG_FATAL("XrlRouter did not become ready.  No Finder?");	}	while(!test_peer.done()) {	    eventloop.run();	}    } catch(...) {	xorp_catch_standard_exceptions();    }    //    // Gracefully stop and exit xlog    //    xlog_stop();    xlog_exit();    debug_msg("Bye!\n");    return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?