示例#1
0
static void
regress_sockaddr_port_format(void *ptr)
{
	struct sockaddr_storage ss;
	int len;
	const char *cp;
	char cbuf[128];
	int r;

	len = sizeof(ss);
	r = evutil_parse_sockaddr_port("192.168.1.1:80",
	    (struct sockaddr*)&ss, &len);
	tt_int_op(r,==,0);
	cp = evutil_format_sockaddr_port_(
		(struct sockaddr*)&ss, cbuf, sizeof(cbuf));
	tt_ptr_op(cp,==,cbuf);
	tt_str_op(cp,==,"192.168.1.1:80");

	len = sizeof(ss);
	r = evutil_parse_sockaddr_port("[ff00::8010]:999",
	    (struct sockaddr*)&ss, &len);
	tt_int_op(r,==,0);
	cp = evutil_format_sockaddr_port_(
		(struct sockaddr*)&ss, cbuf, sizeof(cbuf));
	tt_ptr_op(cp,==,cbuf);
	tt_str_op(cp,==,"[ff00::8010]:999");

	ss.ss_family=99;
	cp = evutil_format_sockaddr_port_(
		(struct sockaddr*)&ss, cbuf, sizeof(cbuf));
	tt_ptr_op(cp,==,cbuf);
	tt_str_op(cp,==,"<addr with socktype 99>");
end:
	;
}
示例#2
0
void main(int argc, char **argv)
{
        int server_addrlen;
        struct evconnlistener *listener;

        base = event_base_new();
        if (!base) {
                perror("event_base_new()");
                exit(1);
        }

        memset(&client_addr, 0, sizeof(client_addr));
		memset(&server_addr, 0, sizeof(server_addr));
        client_addrlen = sizeof(client_addr);
        server_addrlen = sizeof(server_addr);

        evutil_parse_sockaddr_port(argv[1], (struct sockaddr*)&server_addr, &server_addrlen); 
        evutil_parse_sockaddr_port(argv[2], (struct sockaddr*)&client_addr, &client_addrlen);

        listener = evconnlistener_new_bind(base, accept_cb, NULL,
            LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE,
            -1, (struct sockaddr*)&server_addr, server_addrlen);

        event_base_dispatch(base);

        evconnlistener_free(listener);
        event_base_free(base);

}
示例#3
0
	int
main(int argc, char **argv)
{
	int socklen;

	struct evconnlistener *listener;

	if (argc < 3)
		syntax();
	memset(&listen_on_addr, 0, sizeof(listen_on_addr));
	socklen = sizeof(listen_on_addr);
	if (evutil_parse_sockaddr_port(argv[1], (struct sockaddr*)&listen_on_addr, &socklen) < 0) 
	{
		int p = atoi(argv[1]);
		struct sockaddr_in *sin = (struct sockaddr_in*)&listen_on_addr;
		if (p < 1 || p > 65535)
			syntax();
		sin->sin_port = htons(p);
		sin->sin_addr.s_addr = htonl(0x7f000001);
		sin->sin_family = AF_INET;
		socklen = sizeof(struct sockaddr_in);
	}

	memset(&connect_to_addr, 0, sizeof(connect_to_addr));
	connect_to_addrlen = sizeof(connect_to_addr);
	if (evutil_parse_sockaddr_port(argv[2], (struct sockaddr*)&connect_to_addr, &connect_to_addrlen) < 0)
		syntax();

	base = event_base_new();
	if (!base) {
		perror("event_base_new()");
		return 1;
	}


	listener = evconnlistener_new_bind(base, accept_cb, NULL,
			LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE,
			-1, (struct sockaddr*)&listen_on_addr, socklen);

	if (! listener) {
		fprintf(stderr, "Couldn't open listener.\n");
		event_base_free(base);
		return 1;
	}
	event_base_dispatch(base);

	evconnlistener_free(listener);
	event_base_free(base);

	return 0;
}
示例#4
0
文件: Admin.c 项目: bringhurst/cjdns
// only in child
void child(Dict* config, struct ChildContext* context)
{
    context->dataFromParent =
        event_new(context->eventBase,
                  context->inFd,
                  EV_READ | EV_PERSIST,
                  incomingFromParent,
                  context);

    event_add(context->dataFromParent, NULL);

    struct sockaddr_storage addr;
    int addrLen = sizeof(struct sockaddr_storage);
    char* bindTo = "127.0.0.1:9999";
    String* bindStr = Dict_getString(config, BSTR("bind"));
    if (bindStr) {
        fprintf(stderr, "Admin: Binding to %s\n", bindStr->bytes);
        if (evutil_parse_sockaddr_port(bindStr->bytes, (struct sockaddr*) &addr, &addrLen)) {
            fprintf(stderr, "Admin: admin.bind parse failed, calling back on %s\n", bindTo);
            bindStr = NULL;
        }
    }
    if (!bindStr) {
        fprintf(stderr, "Admin: Binding to %s\n", bindTo);
        evutil_parse_sockaddr_port(bindTo, (struct sockaddr*) &addr, &addrLen);
    }

    evutil_socket_t listener = socket(addr.ss_family, SOCK_STREAM, 0);
    evutil_make_socket_nonblocking(listener);
    evutil_make_listen_socket_reuseable(listener);

    if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("bind");
        return;
    }
    if (listen(listener, 16)<0) {
        perror("listen");
        return;
    }

    context->socketEvent =
        event_new(context->eventBase, listener, EV_READ | EV_PERSIST, acceptConn, context);
    event_add(context->socketEvent, NULL);

    if (!context->eventBase) {
        exit(-1);
    }

    event_base_dispatch(context->eventBase);
}
示例#5
0
int
main (int argc, char const *argv[])
{
	int rate;
	struct event_base* base;
	struct bufferevent* bev;
	struct sockaddr address;
	int address_len = sizeof(struct sockaddr);
	
	if (argc != 3)
		usage(argv[0]);

	if (evutil_parse_sockaddr_port(argv[1], &address, &address_len) == -1)
		usage(argv[0]);
	rate = atoi(argv[2]);
	
	base = event_base_new();    
	bev = connect_to_proposer(base, &address);
	
	char value[] = "hello!";
	int len = strlen(value) + 1;
	
	while(1) {
		int i;
		for (i = 0; i < rate; ++i) {
			paxos_submit(bev, value, len);
			event_base_dispatch(base);   //分发事件
		}
		sleep(10);
	}
	return 0;
}
示例#6
0
static void reconf(struct event_base* eventbase,
                   Dict* mainConf,
                   struct Log* logger,
                   struct Allocator* alloc)
{
    Dict* adminConf = Dict_getDict(mainConf, String_CONST("admin"));
    String* address = Dict_getString(adminConf, String_CONST("bind"));
    String* password = Dict_getString(adminConf, String_CONST("password"));

    if (!(address && password)) {
        Log_critical(logger, "Can't get the admin address and password from conf file.");
        exit(-1);
    }

    struct sockaddr_storage addr;
    memset(&addr, 0, sizeof(struct sockaddr_storage));
    int addrLen = sizeof(struct sockaddr_storage);
    if (evutil_parse_sockaddr_port(address->bytes, (struct sockaddr*) &addr, &addrLen)) {
        Log_critical(logger, "Unable to parse [%s] as an ip address port, "
                             "eg: 127.0.0.1:11234", address->bytes);
        exit(-1);
    }

    Configurator_config(mainConf, &addr, addrLen, password, eventbase, logger, alloc);
}
示例#7
0
bool TorControlConnection::Connect(const std::string &target, const ConnectionCB& _connected, const ConnectionCB&  _disconnected)
{
    if (b_conn)
        Disconnect();
    // Parse target address:port
    struct sockaddr_storage connect_to_addr;
    int connect_to_addrlen = sizeof(connect_to_addr);
    if (evutil_parse_sockaddr_port(target.c_str(),
        (struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0) {
        LogPrintf("tor: Error parsing socket address %s\n", target);
        return false;
    }

    // Create a new socket, set up callbacks and enable notification bits
    b_conn = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
    if (!b_conn)
        return false;
    bufferevent_setcb(b_conn, TorControlConnection::readcb, NULL, TorControlConnection::eventcb, this);
    bufferevent_enable(b_conn, EV_READ|EV_WRITE);
    this->connected = _connected;
    this->disconnected = _disconnected;

    // Finally, connect to target
    if (bufferevent_socket_connect(b_conn, (struct sockaddr*)&connect_to_addr, connect_to_addrlen) < 0) {
        LogPrintf("tor: Error connecting to address %s\n", target);
        return false;
    }
    return true;
}
示例#8
0
文件: net.c 项目: libbtc/libbtc
btc_bool btc_node_set_ipport(btc_node *node, const char *ipport)
{
    int outlen = (int)sizeof(node->addr);

    //return true in case of success (0 == no error)
    return (evutil_parse_sockaddr_port(ipport, &node->addr, &outlen) == 0);
}
示例#9
0
int main(int argc, char **argv)
{
    struct sockaddr_in serv_addr;
    struct event_base *base;
    struct bufferevent *bev, *bev_stdout;
    int i, addr_len = sizeof serv_addr;
    struct timeval timeout = {1, 0};
    
    base = event_base_new();
    if (evutil_parse_sockaddr_port("127.0.0.1:8200", (struct sockaddr *)&serv_addr, &addr_len)) {
        printf("evutil_parse_sockaddr_port");
        exit(1);
    }


    for (i = 0; i < 10; i++) {

        bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
        bufferevent_setcb(bev, readcb, writecb, eventcb, NULL);
        bufferevent_enable(bev, EV_READ | EV_WRITE);
        bufferevent_set_timeouts(bev, &timeout, &timeout);
        evbuffer_add_printf(bufferevent_get_output(bev), websocket_request);

        if (bufferevent_socket_connect(bev, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
            bufferevent_free(bev);
            printf("bufferevent_socket_connect");
            exit(1);
        }
    }

    event_base_dispatch(base);
}
示例#10
0
bufferevent * connect_by_ipport(const char * ip_port)
{
	bufferevent * bev =NULL;
	do 
	{
		struct sockaddr saddr;
		int saddr_len =sizeof(saddr);
		if(0!=evutil_parse_sockaddr_port(ip_port, &saddr, &saddr_len))
		{
			printf("evutil_parse_sockaddr_port failed! \n");
			break;
		}

		bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
		int rt =bufferevent_socket_connect(bev,(struct sockaddr *)&saddr, sizeof(saddr));
		if ( rt!= 0) {
				bufferevent_free(bev);
				break;
		}
		bufferevent_setcb(bev, readcb, writecb, eventcb, NULL);
		bufferevent_enable(bev, EV_READ|EV_WRITE);

	} while (0);
	return bev;
}
示例#11
0
int
endpoint_set_ipport(struct endpoint *e,
                    char const *ip)
{
    return evutil_parse_sockaddr_port(ip,
                                      (struct sockaddr *)&e->addr,
                                       (int *)&e->addrlen);
}
示例#12
0
struct UDPInterface* UDPInterface_new(struct event_base* base,
                                      const char* bindAddr,
                                      struct Allocator* allocator,
                                      struct ExceptionHandler* exHandler,
                                      struct Log* logger)
{
    struct UDPInterface* context = allocator->calloc(sizeof(struct UDPInterface), 1, allocator);

    context->messageBuff = allocator->calloc(MAX_PACKET_SIZE + PADDING, 1, allocator);
    context->logger = logger;
    context->allocator = allocator;

    sa_family_t addrFam;
    struct sockaddr_storage addr;
    if (bindAddr != NULL) {
        context->addrLen = sizeof(struct sockaddr_storage);
        if (0 != evutil_parse_sockaddr_port(bindAddr, (struct sockaddr*) &addr, &context->addrLen)) {
            exHandler->exception(__FILE__ " UDPInterface_new() Failed to parse address.",
                                 -1, exHandler);
            return NULL;
        }
        addrFam = addr.ss_family;
    } else {
        addrFam = AF_INET;
        context->addrLen = sizeof(struct sockaddr);
    }

    context->socket = socket(addrFam, SOCK_DGRAM, 0);
    if (context->socket == -1) {
        exHandler->exception(__FILE__ " UDPInterface_new() call to socket() failed.", -3, exHandler);
        return NULL;
    }

    if (bindAddr != NULL) {
        if(bind(context->socket, (struct sockaddr*) &addr, context->addrLen)) {
            exHandler->exception(__FILE__ " UDPInterface_new() Failed to bind socket.",
                                 errno, exHandler);
            return NULL;
        }
    }

    evutil_make_socket_nonblocking(context->socket);

    context->incomingMessageEvent =
        event_new(base, context->socket, EV_READ | EV_PERSIST, handleEvent, context);

    if (context->incomingMessageEvent == NULL) {
        exHandler->exception(__FILE__ " UDPInterface_new() failed to create UDPInterface event.",
                             -4, exHandler);
        return NULL;
    }

    event_add(context->incomingMessageEvent, NULL);

    allocator->onFree(freeEvent, context->incomingMessageEvent, allocator);

    return context;
}
示例#13
0
static int
sockaddr_from_ip_and_port(struct sockaddr_storage * const sockaddr,
                          ev_socklen_t * const sockaddr_len_p,
                          const char * const ip, const char * const port,
                          const char * const error_msg)
{
    char   sockaddr_port[INET6_ADDRSTRLEN + sizeof "[]:65535"];
    int    sockaddr_len_int;
    char  *pnt;
    _Bool  has_column = 0;
    _Bool  has_columns = 0;
    _Bool  has_brackets = *ip == '[';

    if ((pnt = strchr(ip, ':')) != NULL) {
        has_column = 1;
        if (strchr(pnt + 1, ':') != NULL) {
            has_columns = 1;
        }
    }
    sockaddr_len_int = (int) sizeof *sockaddr;
    if ((has_brackets != 0 || has_column != has_columns) &&
        evutil_parse_sockaddr_port(ip, (struct sockaddr *) sockaddr,
                                   &sockaddr_len_int) == 0) {
        *sockaddr_len_p = (ev_socklen_t) sockaddr_len_int;
        return 0;
    }
    if (has_columns != 0 && has_brackets == 0) {
        evutil_snprintf(sockaddr_port, sizeof sockaddr_port, "[%s]:%s",
                        ip, port);
    } else {
        evutil_snprintf(sockaddr_port, sizeof sockaddr_port, "%s:%s",
                        ip, port);
    }
    sockaddr_len_int = (int) sizeof *sockaddr;
    if (evutil_parse_sockaddr_port(sockaddr_port, (struct sockaddr *) sockaddr,
                                   &sockaddr_len_int) != 0) {
        logger(NULL, LOG_ERR, "%s: %s", error_msg, sockaddr_port);
        *sockaddr_len_p = (ev_socklen_t) 0U;

        return -1;
    }
    *sockaddr_len_p = (ev_socklen_t) sockaddr_len_int;

    return 0;
}
示例#14
0
static void
regress_sockaddr_port_parse(void *ptr)
{
	struct sockaddr_storage ss;
	int i, r;

	for (i = 0; sa_port_ents[i].parse; ++i) {
		struct sa_port_ent *ent = &sa_port_ents[i];
		int len = sizeof(ss);
		memset(&ss, 0, sizeof(ss));
		r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len);
		if (r < 0) {
			if (ent->safamily)
				TT_FAIL(("Couldn't parse %s!", ent->parse));
			continue;
		} else if (! ent->safamily) {
			TT_FAIL(("Shouldn't have been able to parse %s!", ent->parse));
			continue;
		}
		if (ent->safamily == AF_INET) {
			struct sockaddr_in sin;
			memset(&sin, 0, sizeof(sin));
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
			sin.sin_len = sizeof(sin);
#endif
			sin.sin_family = AF_INET;
			sin.sin_port = htons(ent->port);
			r = evutil_inet_pton(AF_INET, ent->addr, &sin.sin_addr);
			if (1 != r) {
				TT_FAIL(("Couldn't parse ipv4 target %s.", ent->addr));
			} else if (memcmp(&sin, &ss, sizeof(sin))) {
				TT_FAIL(("Parse for %s was not as expected.", ent->parse));
			} else if (len != sizeof(sin)) {
				TT_FAIL(("Length for %s not as expected.",ent->parse));
			}
		} else {
			struct sockaddr_in6 sin6;
			memset(&sin6, 0, sizeof(sin6));
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
			sin6.sin6_len = sizeof(sin6);
#endif
			sin6.sin6_family = AF_INET6;
			sin6.sin6_port = htons(ent->port);
			r = evutil_inet_pton(AF_INET6, ent->addr, &sin6.sin6_addr);
			if (1 != r) {
				TT_FAIL(("Couldn't parse ipv6 target %s.", ent->addr));
			} else if (memcmp(&sin6, &ss, sizeof(sin6))) {
				TT_FAIL(("Parse for %s was not as expected.", ent->parse));
			} else if (len != sizeof(sin6)) {
				TT_FAIL(("Length for %s not as expected.",ent->parse));
			}
		}
	}
}
示例#15
0
cTCPLinkImplPtr cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cTCPLink::cCallbacksPtr a_LinkCallbacks, cNetwork::cConnectCallbacksPtr a_ConnectCallbacks)
{
	ASSERT(a_LinkCallbacks != nullptr);
	ASSERT(a_ConnectCallbacks != nullptr);

	// Create a new link:
	cTCPLinkImplPtr res{new cTCPLinkImpl(a_LinkCallbacks)};  // Cannot use std::make_shared here, constructor is not accessible
	res->m_ConnectCallbacks = a_ConnectCallbacks;
	cNetworkSingleton::Get().AddLink(res);
	res->m_Callbacks->OnLinkCreated(res);
	res->Enable(res);

	// If a_Host is an IP address, schedule a connection immediately:
	sockaddr_storage sa;
	int salen = static_cast<int>(sizeof(sa));
	if (evutil_parse_sockaddr_port(a_Host.c_str(), reinterpret_cast<sockaddr *>(&sa), &salen) == 0)
	{
		// Insert the correct port:
		if (sa.ss_family == AF_INET6)
		{
			reinterpret_cast<sockaddr_in6 *>(&sa)->sin6_port = htons(a_Port);
		}
		else
		{
			reinterpret_cast<sockaddr_in *>(&sa)->sin_port = htons(a_Port);
		}

		// Queue the connect request:
		if (bufferevent_socket_connect(res->m_BufferEvent, reinterpret_cast<sockaddr *>(&sa), salen) == 0)
		{
			// Success
			return res;
		}
		// Failure
		cNetworkSingleton::Get().RemoveLink(res.get());
		return nullptr;
	}

	// a_Host is a hostname, connect after a lookup:
	if (bufferevent_socket_connect_hostname(res->m_BufferEvent, cNetworkSingleton::Get().GetDNSBase(), AF_UNSPEC, a_Host.c_str(), a_Port) == 0)
	{
		// Success
		return res;
	}
	// Failure
	cNetworkSingleton::Get().RemoveLink(res.get());
	return nullptr;
}
示例#16
0
// Listen for socket connections on a particular interface.
void server_listen(struct event_base *evbase, conninfo_t *conninfo)
{
	struct sockaddr_in sin;
	int len;
	
	assert(evbase);
	assert(_evbase == NULL);
	_evbase = evbase;
	
	assert(_maxconns > 0);
	assert(_conncount == 0);
	assert(_listener == NULL);

	memset(&sin, 0, sizeof(sin));
	// 	sin.sin_family = AF_INET;
	len = sizeof(sin);
	
	assert(_conninfo == NULL);
	_conninfo = conninfo;
	const char *remote_addr = conninfo_remoteaddr(_conninfo);
	assert(remote_addr);
	
	assert(sizeof(struct sockaddr_in) == sizeof(struct sockaddr));
	if (evutil_parse_sockaddr_port(remote_addr, (struct sockaddr *)&sin, &len) != 0) {
		assert(0);
	}
	else {
		
		assert(_listener == NULL);
		assert(_evbase);
		
		logger(LOG_INFO, "listen: %s", remote_addr);

		_listener = evconnlistener_new_bind(
								_evbase,
								accept_conn_cb,
								NULL,
								LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,
								-1,
								(struct sockaddr*)&sin,
								sizeof(sin)
							);
		assert(_listener);
	}
}
示例#17
0
文件: main.cpp 项目: nearmeng/mygame
int main(int argc, char* argv[])
{
	daemon(1, 1);
	glog_init(argv[0]);

	sockaddr addr;
	int len = sizeof(sockaddr);
	evutil_parse_sockaddr_port("127.0.0.1:5000", &addr, &len);

	event_base* pbase = event_base_new();
	char test[32] = "test data";
	evconnlistener* plistener 
		= evconnlistener_new_bind(pbase, listener_cb, reinterpret_cast<void*>(test), LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 10, &addr, len);

	LOG(INFO) << evconnlistener_get_fd(plistener);

	event_base_dispatch(pbase);

	evconnlistener_free(plistener);
	event_base_free(pbase);

	return 0;
}
示例#18
0
static struct Admin* newAdmin(Dict* mainConf,
                              char* user,
                              struct Log* logger,
                              struct event_base* eventBase,
                              struct Allocator* alloc)
{
    Dict* adminConf = Dict_getDict(mainConf, String_CONST("admin"));
    String* address = Dict_getString(adminConf, String_CONST("bind"));
    String* password = Dict_getString(adminConf, String_CONST("password"));

    struct sockaddr_storage addr;
    int addrLen = sizeof(struct sockaddr_storage);
    memset(&addr, 0, sizeof(struct sockaddr_storage));
    if (address) {
        if (evutil_parse_sockaddr_port(address->bytes, (struct sockaddr*) &addr, &addrLen)) {
            Log_critical(logger, "Unable to parse [%s] as an ip address port, "
                                  "eg: 127.0.0.1:11234", address->bytes);
            exit(-1);
        }
    }

    if (!password) {
        uint8_t buff[32];
        randomBase32(buff);
        password = String_new((char*)buff, alloc);
    }

    struct Admin* admin = Admin_new(&addr,
                                    addrLen,
                                    password,
                                    user,
                                    eventBase,
                                    AbortHandler_INSTANCE,
                                    logger,
                                    alloc);
    return admin;
}
示例#19
0
static void
test_evutil_sockaddr_predicates(void *ptr)
{
	struct sockaddr_storage ss;
	int r, i;

	for (i=0; sa_pred_entries[i].parse; ++i) {
		struct sa_pred_ent *ent = &sa_pred_entries[i];
		int len = sizeof(ss);

		r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len);

		if (r<0) {
			TT_FAIL(("Couldn't parse %s!", ent->parse));
			continue;
		}

		/* sockaddr_is_loopback */
		if (ent->is_loopback != evutil_sockaddr_is_loopback_((struct sockaddr*)&ss)) {
			TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected",
				ent->parse));
		}
	}
}
示例#20
0
文件: bitpeer.c 项目: TvdW/bitpeer
int main(int argc, char** argv)
{
	/* Set the CWD */
	char *home = getenv("HOME");
	if (!home) {
		printf("Failed to load data directory\n");
		return EXIT_FAILURE;
	}
	
	char *datadir = malloc(strlen(home) + 10);
	snprintf(datadir, strlen(home) + 10, "%s/.bitpeer", home);
	
	if (chdir(datadir) < 0) {
		if (mkdir(datadir, 0777) < 0) {
			printf("Failed to create data directory.\n");
			return EXIT_FAILURE;
		}
		
		if (chdir(datadir) < 0) {
			printf("Failed to chdir\n");
			return EXIT_FAILURE;
		}
	}
	
	free(datadir);
	
	/* For safety we do these protocol struct assertions */
	assert(sizeof(bp_proto_message_s) == 24);
	assert(sizeof(bp_proto_net_addr_s) == 26);
	assert(sizeof(bp_proto_net_addr_full_s) == 30);
	assert(sizeof(bp_proto_version_s) == 80);
	assert(sizeof(bp_proto_inv_s) == 36);
	assert(sizeof(bp_btcblock_header_s) == 80);
	
	/* Set the settings */
	bp_program_s program;
	memset(&program, 0, sizeof(program));
	program.addrpool_size = 20480;
	program.min_connections = 8;
	program.max_connections = 4096;
	program.reindex_blocks = 0;
	program.relay_transactions = 1;
	program.relay_blocks = 1;
	program.txpool_size = 1024;
	program.blocks_per_getblocks = 500;
	
	/* Interpret the command line */
	if (argc < 2) {
		printf("Invalid command line arguments.\n");
		printf("Usage:  bitpeer [listen_port] [public_ip] -n [seed_node]\n");
		printf("public_ip and seed_node may optionally contain a port number.\n");
		return EXIT_FAILURE;
	}
	
	unsigned short listen_port = atoi(argv[1]);
	if (listen_port == 0) {
		printf("Invalid port number specified. Valid ports go from 1 to 65535.\n");
		return EXIT_FAILURE;
	}
	
	struct sockaddr_in6 sockaddr;
	int sockaddr_len = sizeof(struct sockaddr_in6);
	if (evutil_parse_sockaddr_port(argv[2], (struct sockaddr*)&sockaddr, &sockaddr_len) < 0) {
		printf("Invalid public_ip specified\n");
		return EXIT_FAILURE;
	}
	if (sockaddr.sin6_family == AF_INET) {
		sockaddr = bp_in4to6((struct sockaddr_in*)&sockaddr);
		sockaddr_len = sizeof(struct sockaddr_in6);
	}
	if (sockaddr.sin6_port == 0) {
		sockaddr.sin6_port = ntohs(listen_port);
	}
	
	int nodecount = 0;
	struct sockaddr_in6 *nodeaddrs = NULL;
	int *nodelens = NULL;
	int *nodeperm = NULL;
	
	/* Now interpret the optional arguments */
	// Quick preprocessor macro to go to the next argv
	
#define NEXT_I() {i++; if (i >= argc) { printf("Argument for %s missing\n", argv[i-1]); return EXIT_FAILURE; }}
	for (int i = 3; i < argc; i++) {
		if (strcmp(argv[i], "--reindex") == 0) {
			program.reindex_blocks = 1;
		}
		else if (strcmp(argv[i], "--addnode") == 0  || strcmp(argv[i], "-n") == 0 ||
				 strcmp(argv[i], "--addpnode") == 0 || strcmp(argv[i], "-p") == 0) {
			NEXT_I();
			nodeaddrs = realloc(nodeaddrs, (nodecount+1) * sizeof(struct sockaddr_in6));
			nodelens = realloc(nodelens, (nodecount+1) * sizeof(int));
			nodeperm = realloc(nodeperm, (nodecount+1) * sizeof(int));
			nodelens[nodecount] = sizeof(struct sockaddr_in6);
			nodeperm[nodecount] = 0;
			
			if (strcmp(argv[i-1], "--addpnode") == 0 || strcmp(argv[i-1], "-p") == 0) {
				printf("Adding a permanent node\n");
				nodeperm[nodecount] = 1;
			}
			
			struct sockaddr_in6 *addr = &nodeaddrs[nodecount];
			memset(addr, 0, sizeof(struct sockaddr_in6));
			
			if (evutil_parse_sockaddr_port(argv[i], (struct sockaddr*)addr, nodelens+nodecount) < 0) {
				printf("Invalid node address specified: %s %d\n", argv[i], nodelens[nodecount]);
				return EXIT_FAILURE;
			}
			if (addr->sin6_family == AF_INET) {
				*addr = bp_in4to6((struct sockaddr_in*)addr);
				nodelens[nodecount] = sizeof(struct sockaddr_in6);
			}
			assert(addr->sin6_family == AF_INET6);
			
			if (addr->sin6_port == 0) addr->sin6_port = ntohs(8333);
			
			nodecount += 1;
		}
		else if (strcmp(argv[i], "--txpool") == 0) {
			NEXT_I();
			program.txpool_size = atoi(argv[i]);
			if (program.txpool_size <= 0) {
				printf("Invalid argument for %s\n", argv[i-1]);
				return EXIT_FAILURE;
			}
		}
		else if (strcmp(argv[i], "--addrpool") == 0) {
			NEXT_I();
			program.addrpool_size = atoi(argv[i]);
			if (program.addrpool_size <= 0) {
				printf("Invalid argument for %s\n", argv[i-1]);
				return EXIT_FAILURE;
			}
		}
		else if (strcmp(argv[i], "--getblocks-limit") == 0) {
			NEXT_I();
			program.blocks_per_getblocks = atoi(argv[i]);
			if (program.blocks_per_getblocks == 0) {
				printf("Invalid argument for %s\n", argv[i-1]);
				return EXIT_FAILURE;
			}
		}
		else if (strcmp(argv[i], "--no-tx") == 0) {
			program.relay_transactions = 0;
		}
		else if (strcmp(argv[i], "--no-blocks") == 0) {
			program.relay_blocks = 0;
		}
		else if (strcmp(argv[i], "--minconn") == 0) {
			NEXT_I();
			program.min_connections = atoi(argv[i]);
		}
		else if (strcmp(argv[i], "--maxconn") == 0) {
			NEXT_I();
			program.max_connections = atoi(argv[i]);
			if (program.max_connections <= 0) {
				printf("Invalid argument for %s\n", argv[i-1]);
				return EXIT_FAILURE;
			}
		}
		else if (strcmp(argv[i], "--evdebug") == 0) {
#ifdef EVENT_DBG_ALL
			event_enable_debug_logging(EVENT_DBG_ALL);
#endif
			event_set_log_callback(log_cb);
			event_enable_debug_mode();
		}
		else {
			printf("Unknown argument '%s'\n", argv[i]);
			return EXIT_FAILURE;
		}
	}
	
	/* Ignore SIGPIPE */
	struct sigaction act;
	act.sa_handler = SIG_IGN;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	sigaction(SIGPIPE, &act, NULL);
	
	/* Create the main loop */
	bp_program_init(&program);
	
	program.eventbase = event_base_new();

	/* Set up the signal handler */
	struct event *signal_event = evsignal_new(program.eventbase, SIGINT, signal_cb, &program);
	evsignal_add(signal_event, NULL);
	
	/* Create a server */
	bp_server_s server;
	program.server = &server;
	bp_server_init(&server, &program, (char*)&sockaddr.sin6_addr, ntohs(sockaddr.sin6_port));
	if (bp_server_listen(&server, listen_port) < 0) {
		return EXIT_FAILURE;
	}
	
	/* We need to connect to one initial node in order to seed everything.
	   We will not do this initial discovery ourselves. */
	for (int i = 0; i < nodecount; i++) {
		bp_connection_s *seed_connection = malloc(sizeof(bp_connection_s));
		int status = bp_connection_connect(seed_connection, &server, &nodeaddrs[i], nodelens[i]);
		if (status < 0) {
			printf("Connecting failed\n");
		}
		seed_connection->is_seed = 1;
		seed_connection->is_permanent = nodeperm[i];
	}
	
	free(nodeaddrs);
	free(nodelens);
	free(nodeperm);
	
	/* Run the loop */
	event_base_loop(program.eventbase, 0);
	printf("Entering clean shutdown state\n");

	/* It would appear that our loop ended, so clean up */
	event_free(signal_event);
	bp_server_deinit(&server);
	
	bp_program_deinit(&program);
	event_base_free(program.eventbase);
	
	return EXIT_SUCCESS;
}
示例#21
0
文件: controllers.c 项目: hyper/rqd
//-----------------------------------------------------------------------------
// callback function that will fire when the connection to the controller is reached.
static void controller_connect_handler(int fd, short int flags, void *arg)
{
	controller_t *ct = (controller_t *) arg;
	node_t *node;
	system_data_t *sysdata;
	queue_t *q;
	int error;
	socklen_t foo;
	struct timeval t = {.tv_sec = 1, .tv_usec = 0};
	short int exclusive;

	assert(fd >= 0);
	assert(flags != 0);
	assert(ct);
	assert(ct->node == NULL);
	assert(ct->target);
	assert(ct->sysdata);
	sysdata = ct->sysdata;
	
	// we only need to detect EV_WRITE for a connect event.
	assert(flags == EV_WRITE);

	// remove the connect event
	assert(ct->connect_event);
	event_free(ct->connect_event);
	ct->connect_event = NULL;

	// we are no longer connected.  We are either connected, or not.
	assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTING));
	BIT_CLEAR(ct->flags, FLAG_CONTROLLER_CONNECTING);

	// check to see if we really are connected.
	foo = sizeof(error);
	getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &foo);
	if (error == ECONNREFUSED) {
		// we were connecting, but couldn't.
		BIT_SET(ct->flags, FLAG_CONTROLLER_CLOSED);

		// close the socket that didn't connect.
		close(fd);

		//set the action so that we can attempt to reconnect.
		assert(ct->connect_event == NULL);
		assert(sysdata->evbase);
		ct->connect_event = evtimer_new(sysdata->evbase, controller_wait_handler, (void *) ct);
		evtimer_add(ct->connect_event, &t);
	}
	else {
		logger(((system_data_t *)ct->sysdata)->logging, 2,
			"connected to remote controller: %s", ct->target);
	
		// create the node object.
		node = node_create(sysdata, fd);
	
		// add node to the main nodes list.
		ct->node = node;
		assert(node->controller == NULL);
		node->controller = ct;
		BIT_SET(node->flags, FLAG_NODE_CONTROLLER);
	
		// we need to check to see if we have any queues with active consumers,
		// and if we do, then we need to send consume requests to this node for
		// each one.
		assert(sysdata->queues);
		ll_start(sysdata->queues);
		while ((q = ll_next(sysdata->queues))) {
			assert(q->qid > 0);
			assert(q->name);
	
			if (ll_count(&q->nodes_busy) > 0 || ll_count(&q->nodes_ready) > 0) {
				logger(((system_data_t *)ct->sysdata)->logging, 2, 
					"Sending queue consume ('%s') to alternate controller at %s",
					q->name, ct->target );

				exclusive = 0;
				if (BIT_TEST(q->flags, QUEUE_FLAG_EXCLUSIVE))
					exclusive = 1;
				
				sendConsume(node, q->name, 1, RQ_PRIORITY_LOW, exclusive);
				ll_push_head(&q->nodes_consuming, node);
			}
		}
		ll_finish(sysdata->queues);
	}
}





void controller_connect(controller_t *ct)
{
	evutil_socket_t sock;
	int result;
	int len;

	assert(ct);
	assert(ct->target);
	assert(ct->node == NULL);
	assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTED) == 0);
	assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_FAILED) == 0);
	assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTING) == 0);

	// if not already resolved.... resolve the target.
	if (BIT_TEST(ct->flags, FLAG_CONTROLLER_RESOLVED) == 0) {
		assert(ct->flags == 0);
		
		logger(((system_data_t *)ct->sysdata)->logging, 3, "resolving controller %s.", ct->target);

		len = sizeof(ct->saddr);
		if (evutil_parse_sockaddr_port(ct->target, &ct->saddr, &len) == 0) {
			BIT_SET(ct->flags, FLAG_CONTROLLER_RESOLVED);
		}
		else {
			BIT_SET(ct->flags, FLAG_CONTROLLER_FAILED);
		}
	}
	

	if (BIT_TEST(ct->flags, FLAG_CONTROLLER_FAILED) == 0) {
		assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_RESOLVED));

		BIT_SET(ct->flags, FLAG_CONTROLLER_CONNECTING);

		sock = socket(AF_INET,SOCK_STREAM,0);
		assert(sock >= 0);
						
		// Before we attempt to connect, set the socket to non-blocking mode.
		evutil_make_socket_nonblocking(sock);

		logger(((system_data_t *)ct->sysdata)->logging, 3, "Attempting Remote connect to %s.", ct->target);

		result = connect(sock, &ct->saddr, sizeof(struct sockaddr));
		assert(result < 0);
		assert(errno == EINPROGRESS);

		// connect process has been started.  Now we need to create an event so that we know when the connect has completed.
		assert(ct->connect_event == NULL);
		assert(ct->sysdata);
		assert(((system_data_t *)ct->sysdata)->evbase);
		ct->connect_event = event_new(((system_data_t *)ct->sysdata)->evbase, sock, EV_WRITE, controller_connect_handler, ct);
		event_add(ct->connect_event, NULL);
	}
	else {
		assert(ct->target);
		logger(((system_data_t *)ct->sysdata)->logging, 2, "Remote connect to %s has failed.", ct->target);
	}
}
示例#22
0
文件: le-proxy.c 项目: sambuc/netbsd
int
main(int argc, char **argv)
{
	int i;
	int socklen;

	int use_ssl = 0;
	struct evconnlistener *listener;

	if (argc < 3)
		syntax();

	for (i=1; i < argc; ++i) {
		if (!strcmp(argv[i], "-s")) {
			use_ssl = 1;
		} else if (!strcmp(argv[i], "-W")) {
			use_wrapper = 0;
		} else if (argv[i][0] == '-') {
			syntax();
		} else
			break;
	}

	if (i+2 != argc)
		syntax();

	memset(&listen_on_addr, 0, sizeof(listen_on_addr));
	socklen = sizeof(listen_on_addr);
	if (evutil_parse_sockaddr_port(argv[i],
		(struct sockaddr*)&listen_on_addr, &socklen)<0) {
		int p = atoi(argv[i]);
		struct sockaddr_in *sin = (struct sockaddr_in*)&listen_on_addr;
		if (p < 1 || p > 65535)
			syntax();
		sin->sin_port = htons(p);
		sin->sin_addr.s_addr = htonl(0x7f000001);
		sin->sin_family = AF_INET;
		socklen = sizeof(struct sockaddr_in);
	}

	memset(&connect_to_addr, 0, sizeof(connect_to_addr));
	connect_to_addrlen = sizeof(connect_to_addr);
	if (evutil_parse_sockaddr_port(argv[i+1],
		(struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0)
		syntax();

	base = event_base_new();
	if (!base) {
		perror("event_base_new()");
		return 1;
	}

	if (use_ssl) {
		int r;
		SSL_library_init();
		ERR_load_crypto_strings();
		SSL_load_error_strings();
		OpenSSL_add_all_algorithms();
		r = RAND_poll();
		if (r == 0) {
			fprintf(stderr, "RAND_poll() failed.\n");
			return 1;
		}
		ssl_ctx = SSL_CTX_new(SSLv23_method());
	}

	listener = evconnlistener_new_bind(base, accept_cb, NULL,
	    LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE,
	    -1, (struct sockaddr*)&listen_on_addr, socklen);

	if (! listener) {
		fprintf(stderr, "Couldn't open listener.\n");
		event_base_free(base);
		return 1;
	}
	event_base_dispatch(base);

	evconnlistener_free(listener);
	event_base_free(base);

	return 0;
}
示例#23
0
int
main(int argc, char **argv)
{
	int socklen;
	struct evconnlistener *listener;
	
	if (argc < 2) {
		syntax();
	}
	adapter = ssh_adapter_new();
	if(adapter == NULL) {
		trace_err("ssh_adapter create failed.");
		return 0x01;
	}
	
	//ssh_adapter_options_set(adapter, SSH_BIND_OPTIONS_HOSTKEY, xKEYS_FOLDER "ssh_host_key");
	ssh_adapter_options_set(adapter, SSH_BIND_OPTIONS_DSAKEY, xKEYS_FOLDER "ssh_host_dsa_key");
    ssh_adapter_options_set(adapter, SSH_BIND_OPTIONS_RSAKEY, xKEYS_FOLDER "ssh_host_rsa_key");
	ssh_adapter_options_set(adapter, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "4");
	ssh_adapter_init(adapter);

	memset(&listen_on_addr, 0, sizeof(listen_on_addr));
	socklen = sizeof(listen_on_addr);
	if (evutil_parse_sockaddr_port(argv[1],
		(struct sockaddr*)&listen_on_addr, &socklen)<0) {
		int p = atoi(argv[1]);
		struct sockaddr_in *sin = (struct sockaddr_in*)&listen_on_addr;
		if (p < 1 || p > 65535) {
			syntax();
		}
		sin->sin_port = htons(p);
		sin->sin_addr.s_addr = htonl(0x7f000001);
		sin->sin_family = AF_INET;
		socklen = sizeof(struct sockaddr_in);
	}
	
	memset(&connect_to_addr, 0, sizeof(connect_to_addr));
	connect_to_addrlen = sizeof(connect_to_addr);
	if (evutil_parse_sockaddr_port(argv[2],
		(struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0) {
		syntax();
	}
	base = event_base_new();
	if (!base) {
		perror("event_base_new()");
		return 1;
	}
	
	listener = evconnlistener_new_bind(base, accept_cb, NULL,
	    LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE,
	    -1, (struct sockaddr*)&listen_on_addr, socklen);
	
	if (!listener) {
		fprintf(stderr, "Couldn't open listener.\n");
		event_base_free(base);
		return 1;
	}
	
	event_base_dispatch(base);
	
	evconnlistener_free(listener);
	event_base_free(base);
	
	return 0;
}
示例#24
0
/** @return a string representing the address and port to connect to. */
static String* initAngel(int fromAngel,
                         int toAngel,
                         int corePipes[2][2],
                         struct PipeInterface** piOut,
                         struct EventBase* eventBase,
                         struct Log* logger,
                         struct Allocator* alloc,
                         struct Random* rand)
{
    #define TO_CORE (corePipes[0][1])
    #define FROM_CORE (corePipes[1][0])
    #define TO_ANGEL_AS_CORE (corePipes[1][1])
    #define FROM_ANGEL_AS_CORE (corePipes[0][0])

    Dict core = Dict_CONST(
        String_CONST("fromCore"), Int_OBJ(FROM_CORE), Dict_CONST(
        String_CONST("toCore"), Int_OBJ(TO_CORE), NULL
    ));
    Dict admin = Dict_CONST(
        String_CONST("bind"), String_OBJ(String_CONST("127.0.0.1")), Dict_CONST(
        String_CONST("core"), Dict_OBJ(&core), Dict_CONST(
        String_CONST("pass"), String_OBJ(String_CONST("abcd")), NULL
    )));
    Dict message = Dict_CONST(
        String_CONST("admin"), Dict_OBJ(&admin), NULL
    );

    struct Allocator* tempAlloc;
    BufferAllocator_STACK(tempAlloc, 1024);

    #define BUFFER_SZ 1023
    uint8_t buff[BUFFER_SZ + 1] = {0};
    struct Writer* w = ArrayWriter_new(buff, BUFFER_SZ, tempAlloc);
    StandardBencSerializer_get()->serializeDictionary(w, &message);

    Log_info(logger, "Writing intial configuration to angel on [%d] config: [%s]", toAngel, buff);
    write(toAngel, buff, w->bytesWritten(w));

    // This is angel->core data, we can throw this away.
    //Waiter_getData(buff, BUFFER_SZ, fromAngel, eventBase, NULL);
    //Log_info(logger, "Init message from angel to core: [%s]", buff);
    Bits_memset(buff, 0, BUFFER_SZ);

    struct PipeInterface* pi =
        PipeInterface_new(FROM_ANGEL_AS_CORE, TO_ANGEL_AS_CORE, eventBase, logger, alloc, rand);
    *piOut = pi;

    Log_info(logger, "PipeInterface [%p] is now ready.", (void*)pi);

    // Make sure the angel sends data to the core.
    InterfaceWaiter_waitForData(&pi->generic, eventBase, alloc, NULL);

    // Send response on behalf of core.
    char coreToAngelResponse[128] = "           PADDING              "
        "\xff\xff\xff\xff"
        "d"
          "5:error" "4:none"
        "e";

    char* start = strchr(coreToAngelResponse, '\xff');
    struct Message m = {
        .bytes = (uint8_t*) start,
        .length = strlen(start),
        .padding = start - coreToAngelResponse
    };
    pi->generic.sendMessage(&m, &pi->generic);

    // This is angel->client data, it will tell us which port was bound.
    Waiter_getData(buff, BUFFER_SZ, fromAngel, eventBase, NULL);

    printf("Response from angel to client: [%s]\n", buff);

    struct Reader* reader = ArrayReader_new(buff, BUFFER_SZ, tempAlloc);
    Dict configStore;
    Dict* config = &configStore;
    Assert_true(!StandardBencSerializer_get()->parseDictionary(reader, tempAlloc, config));

    Dict* responseAdmin = Dict_getDict(config, String_CONST("admin"));
    String* bind = Dict_getString(responseAdmin, String_CONST("bind"));
    Assert_true(bind);

    return String_clone(bind, alloc);
}

/**
 * This spawns itself as the Angel process which spawns itself again as the core process.
 * The "core process" pipes all of its inputs back to the originating process
 */

struct AdminTestFramework* AdminTestFramework_setUp(int argc, char** argv)
{
    if (argc > 1 && !strcmp("angel", argv[1])) {
        exit(AngelInit_main(argc, argv));
    }

    struct Allocator* alloc = CanaryAllocator_new(MallocAllocator_new(1<<20), NULL);

    struct Writer* logwriter = FileWriter_new(stdout, alloc);
    Assert_always(logwriter);
    struct Log* logger = WriterLog_new(logwriter, alloc);

    struct EventBase* eventBase = EventBase_new(alloc);
    struct Random* rand = Random_new(alloc, NULL);

    int fromAngel;
    int toAngel;
    int corePipes[2][2];
    if (Pipe_createUniPipe(corePipes[0]) || Pipe_createUniPipe(corePipes[1])) {
        Except_raise(NULL, -1, "Failed to create pipes [%s]", Errno_getString());
    }
    spawnAngel(&fromAngel, &toAngel);

    struct PipeInterface* pi;
    String* addrStr =
        initAngel(fromAngel, toAngel, corePipes, &pi, eventBase, logger, alloc, rand);

    Log_info(logger, "Angel initialized.");

    String* password = String_new("abcd", alloc);
    struct Admin* admin =
        Admin_new(&pi->generic, alloc, logger, eventBase, password);


    // Now setup the client.

    struct sockaddr_storage addr;
    int addrLen = sizeof(struct sockaddr_storage);
    Bits_memset(&addr, 0, sizeof(struct sockaddr_storage));
    Assert_true(!evutil_parse_sockaddr_port(addrStr->bytes, (struct sockaddr*) &addr, &addrLen));

    struct AdminClient* client =
        AdminClient_new((uint8_t*) &addr, addrLen, password, eventBase, logger, alloc);

    Assert_always(client);

    return alloc->clone(sizeof(struct AdminTestFramework), alloc, &(struct AdminTestFramework) {
        .admin = admin,
        .client = client,
        .alloc = alloc,
        .eventBase = eventBase,
        .logger = logger,
        .addr = alloc->clone(addrLen, alloc, &addr),
        .addrLen = addrLen,
        .angelInterface = &pi->generic
    });
}
示例#25
0
static void
echo_read_cb(struct bufferevent *bev, void *ctx)
{
    printf("echo_read_cb ctx:%p\n", ctx);
    /* This callback is invoked when there is data to read on bev. */
    struct evbuffer *input = bufferevent_get_input(bev);

    /* Copy all the data from the input buffer to the output buffer. */
    // evbuffer_add_buffer(output, input);
    // 能读到数据的时候 去连接其他server 而且是以阻塞的方式

    printf("echo_read_cb1 \n");
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    //servaddr.sin_family = AF_INET;
    ////servaddr.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
    //if (inet_aton("192.168.1.104", &servaddr.sin_addr) == 0)
    //{
    //	perror("inet_aton failure!");
    //	printf("address:%u\n", servaddr.sin_addr.s_addr);
    //	exit(EXIT_FAILURE);
    //}

    //servaddr.sin_port = htons(5188); /* Port 9876*/

    // TODO 错误判断
    char buff[64];
    evutil_snprintf(buff, sizeof(buff), "%s:%d", "192.168.1.104", 5188);
    int servadd_len = sizeof(servaddr);
    //int retx = evutil_parse_sockaddr_port("192.168.1.104:5188", (struct sockaddr*)&servaddr, &servadd_len);
    int retx = evutil_parse_sockaddr_port(buff, (struct sockaddr*)&servaddr, &servadd_len);

    printf("address:%s\n", buff);
    if (retx < 0)
    {
        printf("address:error\n");
    }
    else
    {
        printf("address:%u\n", servaddr.sin_addr.s_addr);
    }
    int sockconn;
    errno = 0;
    if ((sockconn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
        perror("socket failure");
        exit(EXIT_FAILURE);
    }
    //evutil_make_socket_nonblocking(sockconn);

    struct timeval	tv;
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    setsockopt(sockconn, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    setsockopt(sockconn, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
    // bufferevent_socket_new 只是分配内存 没有系统调用
    struct bufferevent *bev1 = bufferevent_socket_new(ctx, sockconn, BEV_OPT_CLOSE_ON_FREE);
    //bufferevent_settimeout(bev1, 10, 10);
    //bev1 = bufferevent_socket_new(ctx, -1, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_enable(bev1, EV_READ|EV_WRITE);
    bufferevent_setcb(bev1, NULL, NULL, eventcb, "hello");
    //SetSocketBlockingEnabled(sockconn, 1);

    // 这里默认是阻塞的,会一直阻塞 直到连接成功 或超时 // //
    if (bufferevent_socket_connect(bev1,
                                   (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        /* Error starting connection */
        // 连接不能马上建立的时候 应该添加到写事件中
        fprintf(stderr, "Connect failed.\n");
        perror("connect...........");
        //#define	ETIMEDOUT	110	/* Connection timed out */
        // 无条件超时 非自定义超时  走这里//
        //bufferevent_free(bev1);
        // 此时错误码是 BEV_EVENT_ERROR 在那里销毁 BEV_EVENT_ERROR
        //return -1;
        // 110错误码走到这里  11, 115错误码 不会走到这里
    }
    printf("bufferevent_socket_connect return errno:%d \n", errno);
    ////#define	EAGAIN		11	/* Try again */
    ////#define	ECONNREFUSED	111	/* Connection refused */
    ////#define	EINPROGRESS	115	/* Operation now in progress */ // connect 被超时打断11,


    //
    //if (errno != EAGAIN )
    if (errno == EINPROGRESS) // 自定义 超时中断
    {
        perror("self timeout.............");
        bufferevent_free(bev1);
        return;
    }
    else if (errno != 0)
    {
        perror("00buffevent_connect");
        printf("bufferevent_socket_connect error\n");
        //如果 在过程中 超时会被 打断	EINPROGRESS	115	/* Operation now in progress */

        // 除了自定义超时timeout不宜在这里销毁 在 回调函数中销毁 不然调用不到回调函数//

        //bufferevent_free(bev1);
        return ;
    }
    else
    {
        // 连接成功
        perror("11buffevent_connect");
        printf("bufferevent_socket_connect success\n");
    }


    //if (connect(sockconn, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    //{
    //	perror("connnect error");
    //	exit(EXIT_FAILURE);
    //}
    //else
    //{
    //	printf("connect success\n");
    //}

    //char recvbuf[1024] = {0};
    //memset(recvbuf, 0, sizeof(recvbuf));
    //sleep(5);
    //read(sockconn, recvbuf, sizeof(recvbuf));
    //printf("----%s-----\n", recvbuf);

//	struct evbuffer *input1 = bufferevent_get_input(bev1);
//	printf("before read ---------\n");
//	bufferevent_read_buffer(bev1, input1);
//	size_t len =  evbuffer_get_length(input1);
//	unsigned char * recvbuf = evbuffer_pullup(input1, len);
//	printf("end read len:%ld---------\n", len);
//	printf("----%s-----\n", recvbuf);


    //struct evbuffer * buffer =  evbuffer_new();
    struct evbuffer *buffer = bufferevent_get_input(bev1);
    struct evbuffer *buffero = bufferevent_get_output(bev1);
    evutil_socket_t fd =  bufferevent_getfd(bev1);

    time_t rawtime;
    time ( &rawtime );
    printf("before read ---------%ld\n", rawtime);
    int  ret = evbuffer_read(buffer, fd, 1024);
    // not work
    // bufferevent_read_buffer(bev1, buffer);
    size_t len =  evbuffer_get_length(buffer);
    time ( &rawtime );
    printf("end readlen  ---------%ld\n", len);
    unsigned char * recvbuf = evbuffer_pullup(buffer, len);
    printf("end read    ---------%ld\n", rawtime);
    printf("----%s-----\n", recvbuf);
    evbuffer_drain(buffer, len);
    // int evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd);
    time ( &rawtime );
    printf("before write---------%ld\n", rawtime);
    sleep(10);
    time ( &rawtime );
    printf("before write1---------%ld\n", rawtime);
    evbuffer_add(buffero, "hello,china", 12);
    ret = evbuffer_write(buffero, fd);
    // ret =write(fd, "hello,china", 12);
    if (ret < 0)
    {
        if (errno != 0)
        {
            perror("write ");
        }
    }

    time ( &rawtime );
    printf("end write1   ---------%ld\n", rawtime);

    // 出现read 在connect 之前//
    //root@debian:~/programming/libevent/libevent2/libevent/sample/study-buffevent_block# ./echoserver_block
    //	create listener success, base:0xfdbc40
    //	echo_read_cb ctx:0xfdbc40
    //	echo_read_cb1
    //	bufferevent_socket_connect return errno:11
    //	11buffevent_connect: Resource temporarily unavailable
    //	bufferevent_socket_connect success
    //	----hello,world-----
    //	Connect okay,-------------------------- hello.
    //	disConnect --------------------------.

}
示例#26
0
文件: imap.c 项目: lntoly/skeeter
int
imap_driver_init(struct module *module, struct event_base *base)
{
    struct imap_driver *driver = module->priv;
    struct imap_config *config;
    struct imap_handler *handler = handlers;
    struct module *ldap;
    struct sockaddr_in6 sin;
    int socklen = sizeof(sin);

    assert(driver && driver->config && base);
    config = driver->config;

    driver->base = base;
    driver->dnsbase = get_dnsbase();

    if (config->cert) {
        driver->ssl_ctx = new_ssl_ctx(config->cert, config->pkey);
        if (driver->ssl_ctx == NULL) {
            return 1;
        }
    } else {
        /* skip the STARTTLS handler */
        handler += 1;
    }

    for (; handler->command; handler++) {
        /* handle the private handler storage */
        if (avl_insert(&driver->commands, handler, imap_handler_cmp, avl_dup_error)) {
            return 1;
        }
    }

    if (evutil_parse_sockaddr_port(config->listen, (struct sockaddr *)&sin, &socklen)) {
        return 1;
    }

    /* we start in disabled state until the LDAP interface is ready */
    driver->listener = evconnlistener_new_bind(base, listen_cb, (void*)driver,
            LEV_OPT_REUSEABLE|LEV_OPT_DISABLED|LEV_OPT_CLOSE_ON_FREE,
            -1, (struct sockaddr *)&sin, socklen);
    /* could also be wise to set an error callback, but what errors do we face
     * on accept()? */

    if (!driver->listener) {
        skeeter_log(LOG_CRIT, "Could not create a listener!");
        return 1;
    }

    ldap = get_module("ldap");
    if (!ldap || !ldap->register_event) {
        skeeter_log(LOG_CRIT, "LDAP module not available!");
        return 1;
    }

    if (ldap->register_event(ldap, MODULE_ANY | MODULE_PERSIST, trigger_listener, driver->listener)) {
        skeeter_log(LOG_CRIT, "Regitration with LDAP module failed!");
        return 1;
    }

    driver->ldap = ldap;

    return 0;
}
示例#27
0
int main(int argc, char** argv)
{
    #ifdef Log_KEYS
        fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n");
    #endif

    Assert_true(argc > 0);
    struct Except* eh = NULL;

    // Allow it to allocate 4MB
    struct Allocator* allocator = MallocAllocator_new(1<<22);
    struct Random* rand = Random_new(allocator, eh);
    struct EventBase* eventBase = EventBase_new(allocator);

    if (argc == 2) {
        // one argument
        if (strcmp(argv[1], "--help") == 0) {
            return usage(argv[0]);
        } else if (strcmp(argv[1], "--genconf") == 0) {
            return genconf(rand);
        } else if (strcmp(argv[1], "--pidfile") == 0) {
            // Performed after reading the configuration
        } else if (strcmp(argv[1], "--reconf") == 0) {
            // Performed after reading the configuration
        } else if (strcmp(argv[1], "--bench") == 0) {
            return benchmark();
        } else if (strcmp(argv[1], "--version") == 0) {
            //printf("Version ID: %s\n", RouterModule_gitVersion());
            return 0;
        } else {
            fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]);
            fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
            return -1;
        }
    } else if (argc >  2) {
        // more than one argument?
        fprintf(stderr, "%s: too many arguments\n", argv[0]);
        fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
        return -1;
    }

    if (isatty(STDIN_FILENO)) {
        // We were started from a terminal
        // The chances an user wants to type in a configuration
        // bij hand are pretty slim so we show him the usage
        return usage(argv[0]);
    } else {
        // We assume stdin is a configuration file and that we should
        // start routing
    }

    struct Reader* stdinReader = FileReader_new(stdin, allocator);
    Dict config;
    if (JsonBencSerializer_get()->parseDictionary(stdinReader, allocator, &config)) {
        fprintf(stderr, "Failed to parse configuration.\n");
        return -1;
    }

    struct Writer* logWriter = FileWriter_new(stdout, allocator);
    struct Log* logger = WriterLog_new(logWriter, allocator);

    // --------------------- Setup Pipes to Angel --------------------- //
    int pipeToAngel[2];
    int pipeFromAngel[2];
    if (Pipe_createUniPipe(pipeToAngel) || Pipe_createUniPipe(pipeFromAngel)) {
        Except_raise(eh, -1, "Failed to create pipes to angel [%s]", Errno_getString());
    }

    char pipeToAngelStr[8];
    snprintf(pipeToAngelStr, 8, "%d", pipeToAngel[0]);
    char pipeFromAngelStr[8];
    snprintf(pipeFromAngelStr, 8, "%d", pipeFromAngel[1]);
    char* args[] = { "angel", pipeToAngelStr, pipeFromAngelStr, NULL };

    // --------------------- Spawn Angel --------------------- //
    String* corePath = Dict_getString(&config, String_CONST("corePath"));
    String* privateKey = Dict_getString(&config, String_CONST("privateKey"));

    if (!corePath) {
        corePath = getCorePath(allocator);
        if (!corePath) {
            Except_raise(eh, -1, "Can't find a usable cjdns core executable, "
                                 "try specifying the location in your cjdroute.conf");
        } else {
            Log_warn(logger, "Cjdns core executable was not specified in cjdroute.conf, "
                             "guessing its location.");
        }
    }

    if (!privateKey) {
        Except_raise(eh, -1, "Need to specify privateKey.");
    }
    Log_info(logger, "Forking angel to background.");
    Process_spawn(corePath->bytes, args);

    // --------------------- Get Admin  --------------------- //
    Dict* configAdmin = Dict_getDict(&config, String_CONST("admin"));
    String* adminPass = Dict_getString(configAdmin, String_CONST("password"));
    String* adminBind = Dict_getString(configAdmin, String_CONST("bind"));
    if (!adminPass) {
        adminPass = String_newBinary(NULL, 32, allocator);
        Random_base32(rand, (uint8_t*) adminPass->bytes, 32);
        adminPass->len = strlen(adminPass->bytes);
    }
    if (!adminBind) {
        adminBind = String_new("127.0.0.1:0", allocator);
    }

    // --------------------- Get user for angel to setuid() ---------------------- //
    String* securityUser = NULL;
    List* securityConf = Dict_getList(&config, String_CONST("security"));
    for (int i = 0; i < List_size(securityConf); i++) {
        securityUser = Dict_getString(List_getDict(securityConf, i), String_CONST("setuser"));
        if (securityUser) {
            break;
        }
    }

    // --------------------- Pre-Configure Angel ------------------------- //
    Dict* preConf = Dict_new(allocator);
    Dict* adminPreConf = Dict_new(allocator);
    Dict_putDict(preConf, String_CONST("admin"), adminPreConf, allocator);
    Dict_putString(adminPreConf, String_CONST("core"), corePath, allocator);
    Dict_putString(preConf, String_CONST("privateKey"), privateKey, allocator);
    Dict_putString(adminPreConf, String_CONST("bind"), adminBind, allocator);
    Dict_putString(adminPreConf, String_CONST("pass"), adminPass, allocator);
    if (securityUser) {
        Dict_putString(adminPreConf, String_CONST("user"), securityUser, allocator);
    }

    #define CONFIG_BUFF_SIZE 1024
    uint8_t buff[CONFIG_BUFF_SIZE] = {0};
    struct Writer* toAngelWriter = ArrayWriter_new(buff, CONFIG_BUFF_SIZE - 1, allocator);
    if (StandardBencSerializer_get()->serializeDictionary(toAngelWriter, preConf)) {
        Except_raise(eh, -1, "Failed to serialize pre-configuration");
    }
    write(pipeToAngel[1], buff, toAngelWriter->bytesWritten(toAngelWriter));
    Log_keys(logger, "Sent [%s] to angel process.", buff);

    // --------------------- Get Response from Angel --------------------- //

    uint32_t amount = Waiter_getData(buff, CONFIG_BUFF_SIZE, pipeFromAngel[0], eventBase, eh);
    Dict responseFromAngel;
    struct Reader* responseFromAngelReader = ArrayReader_new(buff, amount, allocator);
    if (StandardBencSerializer_get()->parseDictionary(responseFromAngelReader,
                                                      allocator,
                                                      &responseFromAngel))
    {
        Except_raise(eh, -1, "Failed to parse pre-configuration response [%s]", buff);
    }

    // --------------------- Get Admin Addr/Port/Passwd --------------------- //
    Dict* responseFromAngelAdmin = Dict_getDict(&responseFromAngel, String_CONST("admin"));
    adminBind = Dict_getString(responseFromAngelAdmin, String_CONST("bind"));
    struct sockaddr_storage adminAddr;
    Bits_memset(&adminAddr, 0, sizeof(struct sockaddr_storage));
    int adminAddrLen = sizeof(struct sockaddr_storage);
    if (!adminBind) {
        Except_raise(eh, -1, "didn't get address and port back from angel");
    }
    if (evutil_parse_sockaddr_port(adminBind->bytes,
                                   (struct sockaddr*) &adminAddr,
                                   &adminAddrLen))
    {
        Except_raise(eh, -1, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234",
                     adminBind->bytes);
    }

    // --------------------- Configuration ------------------------- //
    Configurator_config(&config,
                        (uint8_t*)&adminAddr,
                        adminAddrLen,
                        adminPass,
                        eventBase,
                        logger,
                        allocator);

    return 0;
}
示例#28
0
文件: hppm.cpp 项目: hdhog/hppm
int
main (int argc, char **argv)
{
  int
    i,
    socklen,
    erroffset,
    options = 0;
  pfilter_info
    pfi = NULL;
  pattern *
    p;
  struct evconnlistener *
    listener;
  const char *
    error;
  const unsigned char *
    re_tables = NULL;

  if (argc < 3)
    syntax ();

  for (i = 1; i < argc; ++i)
    {
      if (!strcmp (argv[i], "-l"))
	{
	  callback_info::logging = true;
	  ++i;
	  if (i > argc)
	    {
	      syntax ();
	      break;
	    }
	  strncpy (logfile, argv[i], MY_MAX_PATH);
	  logfile[MY_MAX_PATH - 1] = '\0';
	  printf ("Logging to: %s enabled\n", logfile);
	}
      else if (!strcmp (argv[i], "-r"))
	{
	  callback_info::filtering = true;
	  ++i;
	  if (i > argc)
	    {
	      syntax ();
	      break;
	    }
	  strncpy (regexp, argv[i], MY_MAX_PATH);
	  regexp[MY_MAX_PATH - 1] = '\0';
	  printf ("Regexp: %s added to filter chain\n", regexp);
	  if (!pfi)
	    {
	      pfi = (pfilter_info) malloc (sizeof (filter_info));
	      callback_info::pfi = pfi;
	      pfi->patterns = new std::vector < ppattern >;
	    }
	  p = new pattern;
	  p->raw_pattern = regexp;
	  re_tables = pcre_maketables ();
	  p->re = pcre_compile (regexp, options, &error, &erroffset, NULL);
	  p->extra_re = pcre_study (p->re, 0, &error);
	  if (!p->re || !p->extra_re)
	    syntax ();
	  callback_info::pfi->patterns->push_back (p);
	}
      else
	break;
    }

  if (i + 2 != argc)
    syntax ();

#ifdef WIN32
  WORD
    wVersionRequested;
  WSADATA
    wsaData;
  int
    err;
  wVersionRequested = MAKEWORD (2, 2);

  err = WSAStartup (wVersionRequested, &wsaData);
  if (err != 0)
    {
      printf ("WSAStartup failed with error: %d\n", err);
      return 1;
    }
#endif
  memset (&listen_on_addr, 0, sizeof (listen_on_addr));
  socklen = sizeof (listen_on_addr);
  if (evutil_parse_sockaddr_port (argv[i],
				  (struct sockaddr *) &listen_on_addr,
				  &socklen) < 0)
    {
      int
	p = atoi (argv[i]);
      struct sockaddr_in *
	sin = (struct sockaddr_in *) &listen_on_addr;
      if (p < 1 || p > 65535)
	syntax ();
      sin->sin_port = htons (p);
      sin->sin_addr.s_addr = htonl (0x7f000001);
      sin->sin_family = AF_INET;
      socklen = sizeof (struct sockaddr_in);
    }

  memset (&connect_to_addr, 0, sizeof (connect_to_addr));
  connect_to_addrlen = sizeof (connect_to_addr);
  if (evutil_parse_sockaddr_port (argv[i + 1],
				  (struct sockaddr *) &connect_to_addr,
				  &connect_to_addrlen) < 0)
    syntax ();

  if (callback_info::logging)
    {
      if (!(callback_info::fd_out = fopen (logfile, "wb")))
	{
	  syntax ();
	}

    }

  base = event_base_new ();
  if (!base)
    {
      perror ("event_base_new()");
      return 1;
    }

  listener = evconnlistener_new_bind (base, accept_cb, NULL,
				      LEV_OPT_CLOSE_ON_FREE |
				      LEV_OPT_CLOSE_ON_EXEC |
				      LEV_OPT_REUSEABLE, -1,
				      (struct sockaddr *) &listen_on_addr,
				      socklen);

  event_base_dispatch (base);

  if (callback_info::logging)
    {
      fclose (callback_info::fd_out);
    }

  if (callback_info::filtering)
    {
      callback_info::pfi->patterns->~vector ();
      free (callback_info::pfi);
    }

  evconnlistener_free (listener);
  event_base_free (base);

  return 0;
}
示例#29
0
struct Interface* insertEndpoint(struct sockaddr_storage* addr,
                                 struct UDPInterface* context)
{
    if (context->endpointCount >= MAX_INTERFACES) {
        return NULL;
    }

    struct Allocator* epAllocator = context->allocator->child(context->allocator);
    struct Endpoint* ep = &context->endpoints[context->endpointCount];
    memcpy(&ep->addr, addr, sizeof(struct sockaddr_storage));

    struct Interface iface = {
        .senderContext = context,
        .sendMessage = sendMessage,
        .allocator = epAllocator,
        .maxMessageLength = MAX_PACKET_SIZE,
        .requiredPadding = 0
    };
    memcpy(&ep->interface, &iface, sizeof(struct Interface));

    epAllocator->onFree(closeInterface, &ep->interface, epAllocator);

    context->addresses[context->endpointCount] = getAddr(addr);
    context->endpointCount++;

    return &ep->interface;
}

struct Interface* UDPInterface_addEndpoint(struct UDPInterface* context,
                                           const char* endpointSockAddr,
                                           struct ExceptionHandler* exHandler)
{
    struct sockaddr_storage addr;
    int addrLen = sizeof(struct sockaddr_storage);
    if (0 != evutil_parse_sockaddr_port(endpointSockAddr, (struct sockaddr*) &addr, &addrLen)) {
        exHandler->exception(__FILE__ " UDPInterface_addEndpoint() failed to parse address.",
                             -1, exHandler);
        return NULL;
    }
    if (addrLen != context->addrLen) {
        // You can't just bind to an ip4 address then start sending ip6 traffic
        exHandler->exception(__FILE__ " UDPInterface_addEndpoint() address of different type "
                             "then interface.", -1, exHandler);
        return NULL;
    }

    return insertEndpoint(&addr, context);
}

struct Interface* UDPInterface_getDefaultInterface(struct UDPInterface* context)
{
    if (context->defaultInterface == NULL) {
        struct sockaddr_storage sockaddrZero;
        memset(&sockaddrZero, 0, sizeof(struct sockaddr_storage));
        context->defaultInterface = insertEndpoint(&sockaddrZero, context);
    }
    return context->defaultInterface;
}

int UDPInterface_bindToCurrentEndpoint(struct Interface* defaultInterface)
{
    struct UDPInterface* context = (struct UDPInterface*) defaultInterface->senderContext;
    if (context->defaultInterface != defaultInterface
        || context->defaultInterfaceSender == NULL)
    {
        return -1;
    }
    for (uint32_t i = 0; i < context->endpointCount; i++) {
        // TODO this can be faster
        if (defaultInterface == &context->endpoints[i].interface) {
            struct Endpoint* ep = &context->endpoints[i];
            memcpy(&ep->addr, context->defaultInterfaceSender, sizeof(struct sockaddr_storage));
            context->addresses[i] = getAddr(&ep->addr);
            context->defaultInterface = NULL;
            return 0;
        }
    }
    assert(!"Couldn't find the interface in the list");
}

/*--------------------Internals--------------------*/

/**
 * Release the event used by this module.
 *
 * @param vevent a void pointer cast of the event structure.
 */
static void freeEvent(void* vevent)
{
    event_del((struct event*) vevent);
    event_free((struct event*) vevent);
}
示例#30
0
int
obfsproxyssh_client_init(obfsproxyssh_t *state)
{
	obfsproxyssh_client_t *client;
	struct sockaddr_storage addr;
	evutil_socket_t sock;
	uint16_t port;
	int rval, len;

	client = calloc(1, sizeof(obfsproxyssh_client_t));
	if (NULL == client) {
		fprintf(stdout, "CMETHOD-ERROR %s Out of memory allocating state\n",
						OBFSPROXYSSH_METHOD);
		return -1;
	}
	client->state = state;

	memset(&addr, 0, sizeof(addr));
	len = sizeof(addr);
	evutil_parse_sockaddr_port(OBFSPROXYSSH_CLIENT_BIND_ADDR ":8080",
					(struct sockaddr *) &addr, &len);
	((struct sockaddr_in *) &addr)->sin_port = 0;	/* Use ephemeral port */
	client->listener = evconnlistener_new_bind(state->base,
			socks_accept_cb, client,
			LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
			-1, (struct sockaddr *) &addr, len);
	if (NULL == client->listener) {
		fprintf(stdout, "CMETHOD-ERROR %s Failed to bind SOCKS socket\n",
						OBFSPROXYSSH_METHOD);
		goto out_error;
	}
	evconnlistener_set_error_cb(client->listener, client_error_cb);

	sock = evconnlistener_get_fd(client->listener);
	len = sizeof(addr);
	rval = getsockname(sock, (struct sockaddr *) &addr, (socklen_t *) &len);
	if (rval) {
		fprintf(stdout, "CMETHOD-ERROR %s Failed to get SOCKS socket addr %d\n",
						OBFSPROXYSSH_METHOD, rval);
		goto out_free_listener;
	}
	port = htons(((struct sockaddr_in *) &addr)->sin_port);

	rval = libssh2_init(0);
	if (rval) {
		fprintf(stdout, "CMETHOD-ERROR %s Failed to initialize libssh2 (%d)\n",
						OBFSPROXYSSH_METHOD, rval);
		goto out_free_listener;
	}

	rval = ssh_client_profile_init(client);
	if (rval) {
		fprintf(stdout, "CMETHOD-ERROR %s Failed to initialize libssh2 algorithms (%d)\n",
						OBFSPROXYSSH_METHOD, rval);
		goto out_free_listener;
	}

	if (0 == state->unsafe_logging)
		log_f(state, "SOCKS: Listening on: TCP port %d", port);
	else
		log_f(state, "SOCKS: Listening on: %s:%d",
				OBFSPROXYSSH_CLIENT_BIND_ADDR, port);

	fprintf(stdout, "CMETHOD %s socks4 %s:%d %s\n", OBFSPROXYSSH_METHOD,
			OBFSPROXYSSH_CLIENT_BIND_ADDR, port,
			OBFSPROXYSSH_CLIENT_CMETHOD_ARGS);

	LIST_INIT(&client->sessions);
	LIST_INIT(&client->arg_cache);
	state->ctxt = client;
	state->shutdown_fn = client_on_shutdown;
	return 0;

out_free_listener:
	evconnlistener_free(client->listener);
out_error:
	free(client);
	return -1;
}