Exemplo n.º 1
0
struct evdns_server_port *
regress_get_dnsserver(struct event_base *base,
    ev_uint16_t *portnum,
    evutil_socket_t *psock,
    evdns_request_callback_fn_type cb,
    void *arg)
{
	struct evdns_server_port *port = NULL;
	evutil_socket_t sock;
	struct sockaddr_in my_addr;

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0) {
		tt_abort_perror("socket");
	}

	evutil_make_socket_nonblocking(sock);

	memset(&my_addr, 0, sizeof(my_addr));
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(*portnum);
	my_addr.sin_addr.s_addr = htonl(0x7f000001UL);
	if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) {
		evutil_closesocket(sock);
		tt_abort_perror("bind");
	}
	port = evdns_add_server_port_with_base(base, sock, 0, cb, arg);
	if (!*portnum)
		*portnum = regress_get_socket_port(sock);
	if (psock)
		*psock = sock;

	return port;
end:
	return NULL;
}
Exemplo n.º 2
0
static void
listener_read_cb(evutil_socket_t fd, short what, void *p)
{
	struct evconnlistener *lev = p;
	int err;
	while (1) {
		struct sockaddr_storage ss;
		socklen_t socklen = sizeof(ss);

		evutil_socket_t new_fd = accept(fd, (struct sockaddr*)&ss, &socklen);
		if (new_fd < 0)
			break;

		if (!(lev->flags & LEV_OPT_LEAVE_SOCKETS_BLOCKING))
			evutil_make_socket_nonblocking(new_fd);

		lev->cb(lev, new_fd, (struct sockaddr*)&ss, (int)socklen,
		    lev->user_data);
	}
	err = evutil_socket_geterror(fd);
	if (EVUTIL_ERR_ACCEPT_RETRIABLE(err))
		return;
	event_sock_warn(fd, "Error from accept() call");
}
Exemplo n.º 3
0
connection::connection(evutil_socket_t client_sock, thread_pool& pool) :
        client_sock(client_sock),
        pool(pool)
{
    log << "Connection created!\n";

    // Устанавливаем нонблок
    if (evutil_make_socket_nonblocking(client_sock) < 0) {
        close(client_sock);
        throw std::runtime_error("failed to set client socket to non-blocking");
    }

    // Создаём буфер
    if ((output_buffer = evbuffer_new()) == nullptr) {
        close(client_sock);
        throw std::runtime_error("client output buffer allocation failed");
    }

    // Создаём цикл событий для клиента
    if ((evbase = event_base_new()) == nullptr) {
        close(client_sock);
        throw std::runtime_error("client event_base creation failed");
    }

    // создаём буфер события
    buf_ev = bufferevent_socket_new(evbase, client_sock, BEV_OPT_CLOSE_ON_FREE);
    if (buf_ev == nullptr) {
        close(client_sock);
        throw std::runtime_error("client buffer_event creation failed");
    }

    // устанавливаем колбеки на это событие
    bufferevent_setcb(buf_ev, buff_on_read, buff_on_write, buff_on_err, this);
    // Включаем их (?) - так надо, чтобы работало
    bufferevent_enable(buf_ev, EV_READ);
}
Exemplo n.º 4
0
int main(int argc, char *argv[])
{
    evutil_socket_t listener;
    listener = socket(AF_INET, SOCK_STREAM, 0);
    assert(listener > 0);
    evutil_make_listen_socket_reuseable(listener);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(LISTEN_PORT);

    if (bind(listener, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
        perror("bind");
        return 1;
    }

    if (listen(listener, LISTEN_BACKLOG) < 0) {
        perror("listen");
        return 1;
    }

    printf ("Listening...\n");

    evutil_make_socket_nonblocking(listener);

    struct event_base *base = event_base_new();
    assert(base != NULL);
    struct event *listen_event;
    listen_event = event_new(base, listener, EV_READ|EV_PERSIST, do_accept, (void*)base);
    event_add(listen_event, NULL);
    event_base_dispatch(base);

    printf("The End.");
    return 0;
}
Exemplo n.º 5
0
void LibEventMain::acceptfn(int listener, short event, void *arg) {
    EventHandler *processor = (EventHandler*) arg;
    LibEventMain *plevent = (LibEventMain*) processor->getParent();

    sockaddr_storage ss;
    socklen_t slen = sizeof(ss);
    // Investigate: Using a loop to accept connections makes it faster?
    int fd = accept(listener, (sockaddr*) &ss, &slen);
    if (fd < 0) {
        // Investigate: Should check EWOULDBLOCK and EAGAIN?
        perror("accept");
        return;
    }
    INFO_OUT("Client connected on fd %d\n", fd);

    bufferevent *bev;
    evutil_make_socket_nonblocking(fd);
    bev = bufferevent_socket_new(plevent->m_ebase, fd, BEV_OPT_CLOSE_ON_FREE);
    processor->setContext((Context*) bev);
    bufferevent_setcb(bev, readfn, NULL, errorfn, arg);
    bufferevent_setwatermark(bev, EV_READ, 0, max_buff);
    bufferevent_enable(bev, EV_READ | EV_WRITE);

}
Exemplo n.º 6
0
void proxyService()
{
    struct event_base *event_base = NULL;
    //struct evdns_base *evdns_base = NULL;
    event_base = event_base_new();
    //evdns_base = evdns_base_new(event_base, 0);
    evutil_socket_t sock;
    struct sockaddr_in my_addr;
    sock = socket(PF_INET, SOCK_DGRAM, 0);
    if(sock == -1) {
        printf("socket create error\n");
        return;
    }
    evutil_make_socket_nonblocking(sock);
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(53);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    if(bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr))<0) {
        printf("bind error\n");
        return;
    }
    evdns_add_server_port_with_base(event_base, sock, 0, evdns_server_callback, NULL);
    event_base_dispatch(event_base);
}
Exemplo n.º 7
0
/**
   * 回调函数会接受三个参数
   * listener 注册的fd
   * event          注册的事件
   * arg       注册时的参数
   */
void DoAccept(evutil_socket_t nListenSock, short event, void *pArg)
{
    // 获取链接的fd
    struct sockaddr_storage oAddr;
    socklen_t nAddrLen = sizeof(oAddr);
    int nConnSock = accept(nListenSock, (struct sockaddr*)&oAddr, &nAddrLen);
    if (nConnSock < 0) {
        perror("accept");
    } else if (nConnSock > FD_SETSIZE) {
        close(nConnSock);
    } else {
        evutil_make_socket_nonblocking(nConnSock); // 设置为非堵塞的socket

        // 获取传入的参数——event base,自对象在DoAccpet中穿件,用于存放所有的fd
        struct event_base *pEventBase = (struct event_base*)pArg;
        // 创建一个缓冲事件,缓冲事件,顾名思义,就是当数据缓冲到一定程度,才触发,而不是只要有数据就触发
        struct bufferevent* pBuffEnt = bufferevent_socket_new(pEventBase, nConnSock, BEV_OPT_CLOSE_ON_FREE);
        bufferevent_setcb(pBuffEnt, ReadCallBack, NULL, ErrorCallBack, NULL);
        // “程度”通过高/低水位来设定
        bufferevent_setwatermark(pBuffEnt, EV_READ, 0, MAX_LINE);
        // 必须调用这句,否则enabled == false
        bufferevent_enable(pBuffEnt, EV_READ|EV_WRITE);
    }
}
Exemplo n.º 8
0
void SocketListen::OnAccept(int fd)
{
	struct sockaddr_in sin;
    socklen_t len = sizeof(sin);
	int socket_fd = accept(fd, (struct sockaddr*)&sin, &len);
	string ip = inet_ntoa(sin.sin_addr);
	//std::cout << __func__ <<" "<<ip<<" "<<"port: "<<sin.sin_port <<" socket_fd = "<<socket_fd<< std::endl;
	if (socket_fd == INVALID_SOCKET || socket_fd == SOCKET_ERROR)
	{
		std::cout << __func__<< " listen error errno = "<< errno << std::endl;
		return ;
	}
	evutil_make_socket_nonblocking(socket_fd);

	SocketStream* ss = SocketStreamMgr::Instance().Add(sin.sin_addr.s_addr, queue_);
	if (!ss)
		return ;
	ss->SetIsShortConnect(is_short_connnect_);
	ss->SetSocketFd(socket_fd);
	ss->buffer_event_ = bufferevent_new(socket_fd, SocketStream::OnReadCb, SocketStream::OnWriteCb, SocketStream::OnErrorCb,ss);
	bufferevent_base_set(base_, ss->buffer_event_);
	bufferevent_enable(ss->buffer_event_, EV_READ | EV_WRITE);
	ss->Connected();
}
Exemplo n.º 9
0
int tcp_connect_server(const char* server_ip, int port)
{
    int sockfd, status, save_errno;
    struct sockaddr_in server_addr;

    memset(&server_addr, 0, sizeof(server_addr) );

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    status = inet_aton(server_ip, &server_addr.sin_addr);

    if( status == 0 ) //the server_ip is not valid value
    {
        errno = EINVAL;
        return -1;
    }

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if( sockfd == -1 )
        return sockfd;


    status = connect(sockfd, (SA*)&server_addr, sizeof(server_addr) );

    if( status == -1 )
    {
        save_errno = errno;
        close(sockfd);
        errno = save_errno; //the close may be error
        return -1;
    }

    evutil_make_socket_nonblocking(sockfd);//设置为非阻塞。

    return sockfd;
}
Exemplo n.º 10
0
void
do_accept(evutil_socket_t listener, short event, void *arg)
{
    struct event_base *base = arg;
    struct sockaddr_storage ss;
    socklen_t slen = sizeof(ss);
	printf("do_accept before");
	fflush(stdout);
    int fd = accept(listener, (struct sockaddr*)&ss, &slen);
		printf("do_accept after %d", fd);
	fflush(stdout);
    if (fd < 0) { // XXXX eagain??
        perror("accept");
    } else if (fd > FD_SETSIZE) {
        close(fd); // XXX replace all closes with EVUTIL_CLOSESOCKET */
    } else {
        struct fd_state *state;
        evutil_make_socket_nonblocking(fd);
        state = alloc_fd_state(base, fd);
        assert(state); /*XXX err*/
        assert(state->write_event);
        event_add(state->read_event, NULL);
    }
}
Exemplo n.º 11
0
void do_accept(evutil_socket_t listener, short event, void *arg)
{
    struct event_base *base = arg;
    struct sockaddr_storage ss;
    socklen_t slen = sizeof(ss);

    int fd = accept(listener, (struct sockaddr *)&ss, &slen);

    printf("accept client : %d max : %d\n",fd,FD_SETSIZE);
    if (fd < 0) {        // XXXX eagain??
        perror("accept");
        //} else if (fd > FD_SETSIZE) {
        //    close(fd);    // XXX replace all closes with EVUTIL_CLOSESOCKET */
    } else {
        struct fd_state *state;
        evutil_make_socket_nonblocking(fd);
        state = alloc_fd_state(base, fd);

        assert(state);    /*XXX err */
        assert(state->write_event);
        struct timeval t = {5,0};
        event_add(state->read_event,&t);
    }
}
Exemplo n.º 12
0
evutil_socket_t get_delay_sock() {
  evutil_socket_t sock;
	struct sockaddr_in server_address;

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0){
    fprintf(stderr, "blad podcas tworzenia socketa opoznien\n");
    exit(-1);
  }

	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr = htonl(INADDR_ANY);
	server_address.sin_port = htons(delay_port);

	if (bind(sock, (struct sockaddr *) &server_address,
	   (socklen_t) sizeof(server_address)) ||
     evutil_make_listen_socket_reuseable(sock) ||
     evutil_make_socket_nonblocking(sock)) {
    fprintf(stderr, "blad podcas wiazania socketa opoznien\n");
    exit(-1);
  }

  return sock;
}
Exemplo n.º 13
0
int tcp_server_init(int port, int listen_num)
{
  int errno_save;
  evutil_socket_t listener;

  listener = ::socket(AF_INET, SOCK_STREAM, 0);
  if( listener == -1 )
    return -1;

  //允许多次绑定同一个地址。要用在socket和bind之间
  evutil_make_listen_socket_reuseable(listener);

  struct sockaddr_in sin;
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = 0;
  sin.sin_port = htons(port);

  if( ::bind(listener, (SA*)&sin, sizeof(sin)) < 0 )
    goto error;

  if( ::listen(listener, listen_num) < 0)
    goto error;


  //跨平台统一接口,将套接字设置为非阻塞状态
  evutil_make_socket_nonblocking(listener);

  return listener;

  error:
    errno_save = errno;
    evutil_closesocket(listener);
    errno = errno_save;

    return -1;
}
Exemplo n.º 14
0
bool cServerHandleImpl::Listen(UInt16 a_Port)
{
	// Make sure the cNetwork internals are innitialized:
	cNetworkSingleton::Get();

	// Set up the main socket:
	// It should listen on IPv6 with IPv4 fallback, when available; IPv4 when IPv6 is not available.
	bool NeedsTwoSockets = false;
	int err;
	evutil_socket_t MainSock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

	if (!IsValidSocket(MainSock))
	{
		// Failed to create IPv6 socket, create an IPv4 one instead:
		err = EVUTIL_SOCKET_ERROR();
		LOGD("Failed to create IPv6 MainSock: %d (%s)", err, evutil_socket_error_to_string(err));
		MainSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (!IsValidSocket(MainSock))
		{
			m_ErrorCode = EVUTIL_SOCKET_ERROR();
			Printf(m_ErrorMsg, "Cannot create socket for port %d: %s", a_Port, evutil_socket_error_to_string(m_ErrorCode));
			return false;
		}

		// Allow the port to be reused right after the socket closes:
		if (evutil_make_listen_socket_reuseable(MainSock) != 0)
		{
			m_ErrorCode = EVUTIL_SOCKET_ERROR();
			Printf(m_ErrorMsg, "Port %d cannot be made reusable: %d (%s). Restarting the server might not work.",
				a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode)
			);
			LOG("%s", m_ErrorMsg.c_str());
		}

		// Bind to all interfaces:
		sockaddr_in name;
		memset(&name, 0, sizeof(name));
		name.sin_family = AF_INET;
		name.sin_port = ntohs(a_Port);
		if (bind(MainSock, reinterpret_cast<const sockaddr *>(&name), sizeof(name)) != 0)
		{
			m_ErrorCode = EVUTIL_SOCKET_ERROR();
			Printf(m_ErrorMsg, "Cannot bind IPv4 socket to port %d: %s", a_Port, evutil_socket_error_to_string(m_ErrorCode));
			evutil_closesocket(MainSock);
			return false;
		}
	}
	else
	{
		// IPv6 socket created, switch it into "dualstack" mode:
		UInt32 Zero = 0;
		#ifdef _WIN32
			// WinXP doesn't support this feature, so if the setting fails, create another socket later on:
			int res = setsockopt(MainSock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char *>(&Zero), sizeof(Zero));
			err = EVUTIL_SOCKET_ERROR();
			NeedsTwoSockets = ((res == SOCKET_ERROR) && (err == WSAENOPROTOOPT));
		#else
			setsockopt(MainSock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char *>(&Zero), sizeof(Zero));
		#endif

		// Allow the port to be reused right after the socket closes:
		if (evutil_make_listen_socket_reuseable(MainSock) != 0)
		{
			m_ErrorCode = EVUTIL_SOCKET_ERROR();
			Printf(m_ErrorMsg, "Port %d cannot be made reusable: %d (%s). Restarting the server might not work.",
				a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode)
			);
			LOG("%s", m_ErrorMsg.c_str());
		}

		// Bind to all interfaces:
		sockaddr_in6 name;
		memset(&name, 0, sizeof(name));
		name.sin6_family = AF_INET6;
		name.sin6_port = ntohs(a_Port);
		if (bind(MainSock, reinterpret_cast<const sockaddr *>(&name), sizeof(name)) != 0)
		{
			m_ErrorCode = EVUTIL_SOCKET_ERROR();
			Printf(m_ErrorMsg, "Cannot bind IPv6 socket to port %d: %d (%s)", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode));
			evutil_closesocket(MainSock);
			return false;
		}
	}
	if (evutil_make_socket_nonblocking(MainSock) != 0)
	{
		m_ErrorCode = EVUTIL_SOCKET_ERROR();
		Printf(m_ErrorMsg, "Cannot make socket on port %d non-blocking: %d (%s)", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode));
		evutil_closesocket(MainSock);
		return false;
	}
	if (listen(MainSock, 0) != 0)
	{
		m_ErrorCode = EVUTIL_SOCKET_ERROR();
		Printf(m_ErrorMsg, "Cannot listen on port %d: %d (%s)", a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode));
		evutil_closesocket(MainSock);
		return false;
	}
	m_ConnListener = evconnlistener_new(cNetworkSingleton::Get().GetEventBase(), Callback, this, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 0, MainSock);
	m_IsListening = true;

	if (!NeedsTwoSockets)
	{
		return true;
	}

	// If a secondary socket is required (WinXP dual-stack), create it here:
	LOGD("Creating a second socket for IPv4");
	evutil_socket_t SecondSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (!IsValidSocket(SecondSock))
	{
		err = EVUTIL_SOCKET_ERROR();
		LOGD("socket(AF_INET, ...) failed for secondary socket: %d, %s", err, evutil_socket_error_to_string(err));
		return true;  // Report as success, the primary socket is working
	}

	// Allow the port to be reused right after the socket closes:
	if (evutil_make_listen_socket_reuseable(SecondSock) != 0)
	{
		m_ErrorCode = EVUTIL_SOCKET_ERROR();
		Printf(m_ErrorMsg, "Port %d cannot be made reusable (second socket): %d (%s). Restarting the server might not work.",
			a_Port, m_ErrorCode, evutil_socket_error_to_string(m_ErrorCode)
		);
		LOG("%s", m_ErrorMsg.c_str());
	}

	// Make the secondary socket nonblocking:
	if (evutil_make_socket_nonblocking(SecondSock) != 0)
	{
		err = EVUTIL_SOCKET_ERROR();
		LOGD("evutil_make_socket_nonblocking() failed for secondary socket: %d, %s", err, evutil_socket_error_to_string(err));
		evutil_closesocket(SecondSock);
		return true;  // Report as success, the primary socket is working
	}

	// Bind to all IPv4 interfaces:
	sockaddr_in name;
	memset(&name, 0, sizeof(name));
	name.sin_family = AF_INET;
	name.sin_port = ntohs(a_Port);
	if (bind(SecondSock, reinterpret_cast<const sockaddr *>(&name), sizeof(name)) != 0)
	{
		err = EVUTIL_SOCKET_ERROR();
		LOGD("Cannot bind secondary socket to port %d: %d (%s)", a_Port, err, evutil_socket_error_to_string(err));
		evutil_closesocket(SecondSock);
		return true;  // Report as success, the primary socket is working
	}

	if (listen(SecondSock, 0) != 0)
	{
		err = EVUTIL_SOCKET_ERROR();
		LOGD("Cannot listen on secondary socket on port %d: %d (%s)", a_Port, err, evutil_socket_error_to_string(err));
		evutil_closesocket(SecondSock);
		return true;  // Report as success, the primary socket is working
	}

	m_SecondaryConnListener = evconnlistener_new(cNetworkSingleton::Get().GetEventBase(), Callback, this, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 0, SecondSock);
	return true;
}
Exemplo n.º 15
0
static void
dns_server(void)
{
        evutil_socket_t sock=-1;
	struct sockaddr_in my_addr;
	struct evdns_server_port *port=NULL;
	struct in_addr resolve_addr;
	struct in6_addr resolve_addr6;
	struct evdns_base *base=NULL;
	struct evdns_request *req=NULL;

	dns_ok = 1;

	base = evdns_base_new(NULL, 0);

	/* Add ourself as the only nameserver, and make sure we really are
	 * the only nameserver. */
	evdns_base_nameserver_ip_add(base, "127.0.0.1:35353");

	tt_int_op(evdns_base_count_nameservers(base), ==, 1);
	/* Now configure a nameserver port. */
	sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock<0) {
                tt_abort_perror("socket");
        }

        evutil_make_socket_nonblocking(sock);

	memset(&my_addr, 0, sizeof(my_addr));
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(35353);
	my_addr.sin_addr.s_addr = htonl(0x7f000001UL);
	if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) {
		tt_abort_perror("bind");
	}
	port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL);

	/* Send some queries. */
	evdns_base_resolve_ipv4(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
					   dns_server_gethostbyname_cb, NULL);
	evdns_base_resolve_ipv6(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
					   dns_server_gethostbyname_cb, NULL);
	resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
	evdns_base_resolve_reverse(base, &resolve_addr, 0,
            dns_server_gethostbyname_cb, NULL);
	memcpy(resolve_addr6.s6_addr,
	    "\xff\xf0\x00\x00\x00\x00\xaa\xaa"
	    "\x11\x11\x00\x00\x00\x00\xef\xef", 16);
	evdns_base_resolve_reverse_ipv6(base, &resolve_addr6, 0,
            dns_server_gethostbyname_cb, (void*)6);

	req = evdns_base_resolve_ipv4(base,
	    "drop.example.com", DNS_QUERY_NO_SEARCH,
	    dns_server_gethostbyname_cb, (void*)(char*)90909);

	evdns_cancel_request(base, req);

	event_dispatch();

	tt_assert(dns_got_cancel);
        test_ok = dns_ok;

end:
        if (port)
                evdns_close_server_port(port);
        if (sock >= 0)
                EVUTIL_CLOSESOCKET(sock);
	if (base)
		evdns_base_free(base, 0);
}
Exemplo n.º 16
0
static void
listener_read_cb(evutil_socket_t fd, short what, void *p)
{
	struct evconnlistener *lev = p;
	int err;
	evconnlistener_cb cb;
	evconnlistener_errorcb errorcb;
	void *user_data;
	LOCK(lev);
	while (1) {
		struct sockaddr_storage ss;
#ifdef WIN32
		int socklen = sizeof(ss);
#else
		socklen_t socklen = sizeof(ss);
#endif
		evutil_socket_t new_fd = accept(fd, (struct sockaddr*)&ss, &socklen);
		if (new_fd < 0)
			break;
		if (socklen == 0) {
			/* This can happen with some older linux kernels in
			 * response to nmap. */
			evutil_closesocket(new_fd);
			continue;
		}

		if (!(lev->flags & LEV_OPT_LEAVE_SOCKETS_BLOCKING))
			evutil_make_socket_nonblocking(new_fd);

		if (lev->cb == NULL) {
			UNLOCK(lev);
			return;
		}
		++lev->refcnt;
		cb = lev->cb;
		user_data = lev->user_data;
		UNLOCK(lev);
		cb(lev, new_fd, (struct sockaddr*)&ss, (int)socklen,
		    user_data);
		LOCK(lev);
		if (lev->refcnt == 1) {
			int freed = listener_decref_and_unlock(lev);
			EVUTIL_ASSERT(freed);
			return;
		}
		--lev->refcnt;
	}
	err = evutil_socket_geterror(fd);
	if (EVUTIL_ERR_ACCEPT_RETRIABLE(err)) {
		UNLOCK(lev);
		return;
	}
	if (lev->errorcb != NULL) {
		++lev->refcnt;
		errorcb = lev->errorcb;
		user_data = lev->user_data;
		UNLOCK(lev);
		errorcb(lev, user_data);
		LOCK(lev);
		listener_decref_and_unlock(lev);
	} else {
		event_sock_warn(fd, "Error from accept() call");
	}
}
Exemplo n.º 17
0
static int
new_peer()
{
	int			 flag = 1;
	int			 fd = -1;
	struct sockaddr_in	 sin;
	SSL_CTX			*ctx;
	SSL			*ssl;

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(0);
	sin.sin_port = htons(9093);

	if ((fd = socket(sin.sin_family, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		jlog(L_ERROR, "socket failed");
		goto out;
	}

	if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(flag)) < 0 ||
	    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) < 0) {
		jlog(L_ERROR, "setsockopt failed");
		goto out;
	}

	if (evutil_make_socket_nonblocking(fd) < 0) {
		jlog(L_ERROR, "evutil_make_socket_nonblocking failed");
		goto out;
	}	

	if ((ctx = evssl_init()) == NULL) {
		jlog(L_ERROR, "evssl_init failed");
		goto out;
	}

	if ((ssl = SSL_new(ctx)) == NULL) {
		jlog(L_ERROR, "SSL_new failed");
		goto out;
	}

	if ((bufev_sock = bufferevent_openssl_socket_new(base, fd, ssl,
	    BUFFEREVENT_SSL_CONNECTING, BEV_OPT_CLOSE_ON_FREE)) == NULL) {
		jlog(L_ERROR, "bufferevent_socket_new failed");
		goto out;
	}

	bufferevent_enable(bufev_sock, EV_READ|EV_WRITE);
	bufferevent_setcb(bufev_sock, on_read_cb, NULL, on_event_cb, NULL);

	if (bufferevent_socket_connect(bufev_sock,
	    (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		jlog(L_ERROR, "bufferevent_socket_connected failed");
		goto out;
	}

	return 0;
out:
	if (bufev_sock != NULL)
		bufferevent_free(bufev_sock);
	return -1;

}
Exemplo n.º 18
0
static tr_socket_t tr_netBindTCPImpl(tr_address const* addr, tr_port port, bool suppressMsgs, int* errOut)
{
    TR_ASSERT(tr_address_is_valid(addr));

    static int const domains[NUM_TR_AF_INET_TYPES] = { AF_INET, AF_INET6 };
    struct sockaddr_storage sock;
    tr_socket_t fd;
    int addrlen;
    int optval;

    fd = socket(domains[addr->type], SOCK_STREAM, 0);

    if (fd == TR_BAD_SOCKET)
    {
        *errOut = sockerrno;
        return TR_BAD_SOCKET;
    }

    if (evutil_make_socket_nonblocking(fd) == -1)
    {
        *errOut = sockerrno;
        tr_netCloseSocket(fd);
        return TR_BAD_SOCKET;
    }

    optval = 1;
    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void const*)&optval, sizeof(optval));
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void const*)&optval, sizeof(optval));

#ifdef IPV6_V6ONLY

    if (addr->type == TR_AF_INET6)
    {
        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void const*)&optval, sizeof(optval)) == -1)
        {
            if (sockerrno != ENOPROTOOPT) /* if the kernel doesn't support it, ignore it */
            {
                *errOut = sockerrno;
                tr_netCloseSocket(fd);
                return TR_BAD_SOCKET;
            }
        }
    }

#endif

    addrlen = setup_sockaddr(addr, htons(port), &sock);

    if (bind(fd, (struct sockaddr*)&sock, addrlen) == -1)
    {
        int const err = sockerrno;

        if (!suppressMsgs)
        {
            char const* fmt;
            char const* hint;
            char err_buf[512];

            if (err == EADDRINUSE)
            {
                hint = _("Is another copy of Transmission already running?");
            }
            else
            {
                hint = NULL;
            }

            if (hint == NULL)
            {
                fmt = _("Couldn't bind port %d on %s: %s");
            }
            else
            {
                fmt = _("Couldn't bind port %d on %s: %s (%s)");
            }

            tr_logAddError(fmt, port, tr_address_to_string(addr), tr_net_strerror(err_buf, sizeof(err_buf), err), hint);
        }

        tr_netCloseSocket(fd);
        *errOut = err;
        return TR_BAD_SOCKET;
    }

    if (!suppressMsgs)
    {
        tr_logAddDebug("Bound socket %" PRIdMAX " to port %d on %s", (intmax_t)fd, port, tr_address_to_string(addr));
    }

#ifdef TCP_FASTOPEN

#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif

    optval = 5;
    setsockopt(fd, SOL_TCP, TCP_FASTOPEN, (void const*)&optval, sizeof(optval));

#endif

    if (listen(fd, 128) == -1)
    {
        *errOut = sockerrno;
        tr_netCloseSocket(fd);
        return TR_BAD_SOCKET;
    }

    return fd;
}
Exemplo n.º 19
0
void
run(void)
{
    evutil_socket_t sender;
    struct sockaddr_in sin;
    struct event_base *base;
    struct event *write_event = NULL;
    struct event *read_event = NULL;
    struct fd_state *state;
    int result;

    base = event_base_new();
    if (!base)
        return; /*XXXerr*/

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_port = htons(40713);

    sender = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    evutil_make_socket_nonblocking(sender);

#ifndef WIN32
    {
        int one = 1;
        setsockopt(sender, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
    }
#endif

    /*
    if (bind(sender, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
        perror("bind");
        return;
    }

    sender_event = event_new(base, sender, EV_READ|EV_PERSIST, do_read, (void*)base);
    /-*XXX check it *-/
    event_add(sender_event, NULL);
    //*/

    result = connect(sender, (struct sockaddr*)&sin, sizeof(sin));
    if (result < 0 || result == SOCKET_ERROR) {
        if (WSAGetLastError() == WSAEWOULDBLOCK) {
            printf("WSAGetLastError() = WSAEWOULDBLOCK\r\n");
            Sleep(1000);
            printf("Press any key to continue...\r\n");
            //system("pause");
        }
        else {
            printf("connect error!\r\n");
            printf("WSAGetLastError() = 0x%08X\r\n", WSAGetLastError());
            system("pause");
            perror("connect");
            return;
        }
    }

    //printf("Press any key to continue...\r\n");
    //system("pause");

    //write_event = event_new(base, sender, EV_WRITE|EV_PERSIST, do_write, (void*)base);
    //read_event  = event_new(base, sender, EV_READ |EV_PERSIST, do_read,  (void*)base);

    state = alloc_fd_state(base, sender);

    /*
    if (write_event) {
        printf("event_add(write_event, NULL);\r\n");
        event_add(write_event, NULL);
    }
    //*/

    if (state && state->write_event) {
        printf("event_add(state->write_event, NULL);\r\n");
        event_add(state->write_event, NULL);
    }

    if (state && state->read_event) {
        printf("event_add(state->read_event, NULL);\r\n");
        event_add(state->read_event, NULL);
    }

    printf("event_base_dispatch(base);\r\n");
    event_base_dispatch(base);

    /*
    if (write_event)
        event_free(write_event);
    if (read_event)
        event_free(read_event);
    //*/

    if (state)
        free_fd_state(state);
}
Exemplo n.º 20
0
void TNonblockingIOThread::createNotificationPipe() {
  if(evutil_socketpair(AF_LOCAL, SOCK_STREAM, 0, notificationPipeFDs_) == -1) {
    GlobalOutput.perror("TNonblockingServer::createNotificationPipe ", EVUTIL_SOCKET_ERROR());
    throw TException("can't create notification pipe");
  }
  if(evutil_make_socket_nonblocking(notificationPipeFDs_[0])<0 ||
     evutil_make_socket_nonblocking(notificationPipeFDs_[1])<0) {
    ::THRIFT_CLOSESOCKET(notificationPipeFDs_[0]);
    ::THRIFT_CLOSESOCKET(notificationPipeFDs_[1]);
    throw TException("TNonblockingServer::createNotificationPipe() THRIFT_O_NONBLOCK");
  }
  for (int i = 0; i < 2; ++i) {
#if LIBEVENT_VERSION_NUMBER < 0x02000000
    int flags;
    if ((flags = THRIFT_FCNTL(notificationPipeFDs_[i], F_GETFD, 0)) < 0 ||
        THRIFT_FCNTL(notificationPipeFDs_[i], F_SETFD, flags | FD_CLOEXEC) < 0) {
#else
    if (evutil_make_socket_closeonexec(notificationPipeFDs_[i]) < 0) {
#endif
      ::THRIFT_CLOSESOCKET(notificationPipeFDs_[0]);
      ::THRIFT_CLOSESOCKET(notificationPipeFDs_[1]);
      throw TException("TNonblockingServer::createNotificationPipe() "
        "FD_CLOEXEC");
    }
  }
}

/**
 * Register the core libevent events onto the proper base.
 */
void TNonblockingIOThread::registerEvents() {
  threadId_ = Thread::get_current();

  assert(eventBase_ == 0);
  eventBase_ = getServer()->getUserEventBase();
  if (eventBase_ == NULL) {
    eventBase_ = event_base_new();
    ownEventBase_ = true;
  }

  // Print some libevent stats
  if (number_ == 0) {
    GlobalOutput.printf("TNonblockingServer: using libevent %s method %s",
            event_get_version(),
            event_base_get_method(eventBase_));
  }

  if (listenSocket_ >= 0) {
    // Register the server event
    event_set(&serverEvent_,
              listenSocket_,
              EV_READ | EV_PERSIST,
              TNonblockingIOThread::listenHandler,
              server_);
    event_base_set(eventBase_, &serverEvent_);

    // Add the event and start up the server
    if (-1 == event_add(&serverEvent_, 0)) {
      throw TException("TNonblockingServer::serve(): "
                       "event_add() failed on server listen event");
    }
    GlobalOutput.printf("TNonblocking: IO thread #%d registered for listen.",
                        number_);
  }

  createNotificationPipe();

  // Create an event to be notified when a task finishes
  event_set(&notificationEvent_,
            getNotificationRecvFD(),
            EV_READ | EV_PERSIST,
            TNonblockingIOThread::notifyHandler,
            this);

  // Attach to the base
  event_base_set(eventBase_, &notificationEvent_);

  // Add the event and start up the server
  if (-1 == event_add(&notificationEvent_, 0)) {
    throw TException("TNonblockingServer::serve(): "
                     "event_add() failed on task-done notification event");
  }
  GlobalOutput.printf("TNonblocking: IO thread #%d registered for notify.",
                      number_);
}
Exemplo n.º 21
0
int main (int argc, char **argv) {
  evutil_socket_t delay_sock, multicast_sock;
  struct event *udp_client_event, *multicast_listener_event, *signal_event,
               *discover_event, *telnet, *telnet_ref;
  opterr = 0;

  int opt;
  while ((opt = getopt (argc, argv, "u:U:t:T:v:s")) != -1) {
    switch (opt) {
      case 'u':
        delay_port = atoi(optarg);
        if(!delay_port) {
          fprintf(stderr, "bledny port opoznien\n");
          return 1;
        }
        break;
      case 'U':
        ui_port = atoi(optarg);
        if(!ui_port) {
          fprintf(stderr, "bledny port telnetu\n");
          return 1;
        }
        break;
      case 't':
        delay_ref = atof(optarg);
        if(delay_ref == 0.0) {
          fprintf(stderr, "bledny czas pomiedzy mierzeniem opoznien\n");
          return 1;
        }
        break;
      case 'T':
        discovery_ref = atof(optarg);
        if(discovery_ref == 0.0) {
          fprintf(stderr, "bledny czas pomiedzy odkrywaniem komputerow\n");
          return 1;
        }
        break;
      case 'v':
        ui_ref = atof(optarg);
        if(ui_ref == 0.0) {
          fprintf(stderr, "bledny czas pomiedzy odkrywaniem odswierzaniem ui\n"
          );
          return 1;
        }
      case 's':
        ssh_tcp = 1;
        break;
      default:
        fprintf(stderr, "bledna opcja\n");
        return 1;
    }
  }

  init_data();
  init_ip();
  init_mdns(ssh_tcp);
  main_loop = event_base_new();
  delay_sock = get_delay_sock();
  multicast_sock = get_multi_sock();

  udp_client_event = event_new(main_loop, delay_sock, EV_READ|EV_PERSIST,
                               udp_delays_ans_cb, NULL);
  if(!udp_client_event) {
    fprintf(stderr, "nie udalo sie utworzyc eventu serwera udp\n");
    exit(-1);
  }

  if(event_add(udp_client_event, NULL) == -1) {
    fprintf(stderr, "nie udalo sie przylaczyc eventu serwera udp\n");
    exit(-1);
  }


  multicast_listener_event = event_new(main_loop, multicast_sock,
      EV_READ|EV_PERSIST, multicast_rcv_cb, NULL);
  if(!multicast_listener_event)  {
    fprintf(stderr, "nie udalo sie utworzyc eventu serwera multicast\n");
    exit(-1);
  }

  if(event_add(multicast_listener_event, NULL) == -1) {
    fprintf(stderr, "nie udalo sie przylaczyc eventu serwera multicast\n");
    exit(-1);
  }

  discover_event = event_new(main_loop, multicast_sock, EV_TIMEOUT|EV_PERSIST,
                    multicast_discover_cb, NULL);

  if(!discover_event || event_add(discover_event, &disc_tv) < 0) {
    fprintf(stderr, "odkrywnie nie uruchomilo sie\n");
    exit(-1);
  }

  signal_event = evsignal_new(main_loop, SIGINT, sigint_cb, (void *)main_loop);

	if (!signal_event || event_add(signal_event, NULL)<0) {
		fprintf(stderr, "Could not create/add a signal event!\n");
		return 1;
	}

  evutil_socket_t uisock = socket(PF_INET, SOCK_STREAM, 0);
  struct sockaddr_in uiadrr;
  uiadrr.sin_family = AF_INET;
  uiadrr.sin_addr.s_addr = htonl(INADDR_ANY);
  uiadrr.sin_port = htons(ui_port);

  if(uisock == -1 ||
     evutil_make_listen_socket_reuseable(uisock) ||
     evutil_make_socket_nonblocking(uisock)) {
   		return 1;
  }
  bind(uisock, (struct sockaddr*)&uiadrr, (socklen_t)sizeof(uiadrr));

  listen(uisock, 5);

  telnet = event_new(main_loop, uisock, EV_READ|EV_PERSIST, telnet_cb, NULL);
  event_add(telnet, NULL);




  telnet_ref = event_new(main_loop, uisock, EV_TIMEOUT|EV_PERSIST,
    telnet_refresh_cb, NULL);
  event_add(telnet_ref, &ui_tv);

  if(event_base_dispatch(main_loop) == -1) {
    fprintf(stderr, "nie udalo sie uruchomic glownej petli\n");
    exit(-1);
  }

  event_free(signal_event);
  event_free(multicast_listener_event);
  event_free(udp_client_event);
  event_base_free(main_loop);

  close(delay_sock);
  close(multicast_sock);

  return 0;
}
Exemplo n.º 22
0
void udp_init(int unused1, short unused2, void *arg) {
    UNUSED(unused1);
    UNUSED(unused2);
    struct event_base *base = arg;
    const char *server_hostname = config_get_remote_hostname();
    const char *port = config_get_remote_port();

    /* Cleanup any existing sockets / bufferevents */
    if (udp_bev) {
        bufferevent_free(udp_bev);
        udp_fd = 1;
    }

    struct addrinfo hints, *result, *rp;
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = 0;
    hints.ai_protocol = 0; /* Any protocol */

    int s = getaddrinfo(server_hostname, port, &hints, &result);
    if (s != 0) {
        log_warn("Failed to resolve %s, retry in %ds", server_hostname,
                 SERVER_RECONNECT_INTERVAL_SEC);
        udp_retry_later(base);
        return;
    }

    /* getaddrinfo() returns a list of address structures.
       Try each address until we successfully connect(2).
       If socket(2) (or connect(2)) fails, we (close the socket
       and) try the next address. */
    for (rp = result; rp != NULL; rp = rp->ai_next) {
        void *p;
        if (rp->ai_addr->sa_family == AF_INET) {
            p = &(((struct sockaddr_in *)rp->ai_addr)->sin_addr);
        } else {
            p = &(((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr);
        }
        char s[INET6_ADDRSTRLEN];
        inet_ntop(rp->ai_family, p, s, sizeof s);
        udp_fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if (udp_fd == -1) {
            continue;
        }
        if (connect(udp_fd, rp->ai_addr, rp->ai_addrlen) != -1) {
            log_notice("Trying connection to %s", s);
            evutil_make_socket_nonblocking(udp_fd);
            udp_bev =
                bufferevent_socket_new(base, udp_fd, BEV_OPT_CLOSE_ON_FREE);
            bufferevent_setcb(udp_bev, udp_readcb, NULL, udp_eventcb, base);
            bufferevent_enable(udp_bev, EV_READ | EV_WRITE);
            break; /* Success */
        } else {
            /* This happens if we can resolve the hostname (because
               it's an IP address) but don't have networking (yet) */
            log_warn("Failed to connect: %s\n", strerror(errno));
            close(udp_fd);
            udp_fd = -1;
            udp_retry_later(base);
        }
    }
    free(result);
    return;
}
Exemplo n.º 23
0
static void *
basic_test_setup(const struct testcase_t *testcase)
{
	struct event_base *base = NULL;
	evutil_socket_t spair[2] = { -1, -1 };
	struct basic_test_data *data = NULL;

#ifndef _WIN32
	if (testcase->flags & TT_ENABLE_IOCP_FLAG)
		return (void*)TT_SKIP;
#endif

	if (testcase->flags & TT_NEED_THREADS) {
		if (!(testcase->flags & TT_FORK))
			return NULL;
#if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED)
		if (evthread_use_pthreads())
			exit(1);
#elif defined(EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED)
		if (evthread_use_windows_threads())
			exit(1);
#else
		return (void*)TT_SKIP;
#endif
	}

	if (testcase->flags & TT_NEED_SOCKETPAIR) {
		if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, spair) == -1) {
			fprintf(stderr, "%s: socketpair\n", __func__);
			exit(1);
		}

		if (evutil_make_socket_nonblocking(spair[0]) == -1) {
			fprintf(stderr, "fcntl(O_NONBLOCK)");
			exit(1);
		}

		if (evutil_make_socket_nonblocking(spair[1]) == -1) {
			fprintf(stderr, "fcntl(O_NONBLOCK)");
			exit(1);
		}
	}
	if (testcase->flags & TT_NEED_BASE) {
		if (testcase->flags & TT_LEGACY)
			base = event_init();
		else
			base = event_base_new();
		if (!base)
			exit(1);
	}
	if (testcase->flags & TT_ENABLE_IOCP_FLAG) {
		if (event_base_start_iocp(base, 0)<0) {
			event_base_free(base);
			return (void*)TT_SKIP;
		}
	}

	if (testcase->flags & TT_NEED_DNS) {
		evdns_set_log_fn(dnslogcb);
		if (evdns_init())
			return NULL; /* fast failure */ /*XXX asserts. */
	}

	if (testcase->flags & TT_NO_LOGS)
		event_set_log_callback(ignore_log_cb);

	data = calloc(1, sizeof(*data));
	if (!data)
		exit(1);
	data->base = base;
	data->pair[0] = spair[0];
	data->pair[1] = spair[1];
	data->setup_data = testcase->setup_data;
	return data;
}
Exemplo n.º 24
0
int main(int argc, char* argv[])
{

#if 1
    // For debug with segment fault
    struct sigaction sa;
    sa.sa_handler = backtrace_info;
    sigaction(SIGSEGV, &sa, NULL);

    // ignore SIGPIPE
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);
    signal(SIGABRT, SIG_IGN);

#endif

    int opt_g = 0;
    memset(&cltopt, 0, sizeof(CLT_OPT));

    cltopt.C_TYPE = C_USR;
    while( (opt_g = getopt(argc, argv, "Dh")) != -1 )
    {
        switch(opt_g)
        {
            case 'D':
                cltopt.C_TYPE = C_DAEMON;
                break;
            case 'h':
            default:
                usage();
                exit(EXIT_SUCCESS);
        }
    }

    if(load_settings_client(&cltopt) == RET_NO)
    {
        st_d_error("加载配置文件settings.json出错!");
        exit(EXIT_FAILURE);
    }

    OpenSSL_add_ssl_algorithms();
    SSL_load_error_strings();
    SSL_library_init();     //SSL_library_init() always returns "1"

    //int sd_id128_from_string(const char *s, sd_id128_t *ret);
    sd_id128_get_machine(&cltopt.mach_uuid);
    gethostname(cltopt.hostname, sizeof(cltopt.hostname)); 
    st_d_print("CURRENT MACH_ID:%s, HOSTNAME:%s", SD_ID128_CONST_STR(cltopt.mach_uuid), 
               cltopt.hostname);

    if (cltopt.C_TYPE == C_DAEMON) 
    {
        cltopt.session_uuid = cltopt.mach_uuid;
        st_d_print("PLEASE REMEMEBER SET MACH_ID FOR USER TYPE!");
    }

    dump_clt_opts(&cltopt);

    /*带配置产生event_base对象*/
    struct event_config *cfg;
    cfg = event_config_new();
    event_config_avoid_method(cfg, "select");   //避免使用select
    event_config_require_features(cfg, EV_FEATURE_ET);  //使用边沿触发类型
    base = event_base_new_with_config(cfg);
    event_config_free(cfg);
    st_d_print("当前复用Event模式: %s", event_base_get_method(base)); // epoll

    /*连接服务器*/
    int srv_fd = socket(AF_INET, SOCK_STREAM, 0);
    unsigned int optval = 1;
    setsockopt(srv_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));//禁用NAGLE算法

    if(sc_connect_srv(srv_fd) != RET_YES) 
    {
        SYS_ABORT("连接服务器失败!");
    }

    if(cltopt.C_TYPE == C_DAEMON) 
    {
        if (sc_daemon_init_srv(srv_fd) != RET_YES) 
            SYS_ABORT("(Daemon) 服务器返回错误!");
    }
    else
    {
        if (sc_usr_init_srv(srv_fd) != RET_YES) 
            SYS_ABORT("(Usr) 服务器返回错误!");
    }

    st_d_print("客户端连接服务器OK!");

    /**
     * USR 建立本地Listen侦听套接字
     */

    if (cltopt.C_TYPE == C_USR)
    {
        int i = 0;
        for (i=0; i<MAX_PORT_NUM; i++)
        {
            if (cltopt.maps[i].usrport) 
            {
                struct evconnlistener *listener;
                struct sockaddr_in sin;
                memset(&sin, 0, sizeof(sin));
                sin.sin_family = AF_INET;
                sin.sin_addr.s_addr = htonl(0);
                sin.sin_port = htons(cltopt.maps[i].usrport); /* Port Num */

                listener = evconnlistener_new_bind(base, accept_conn_cb, &cltopt.maps[i],
                        LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1/*backlog 连接无限制*/,
                        (struct sockaddr*)&sin, sizeof(sin));

                if (!listener) 
                {
                    st_d_error("[USR]创建侦听套接字失败 %d:%d", 
                               cltopt.maps[i].usrport, cltopt.maps[i].daemonport); 
                    continue;
                }
                evconnlistener_set_error_cb(listener, accept_error_cb);

                st_d_print("[USR]创建侦听套接字 %d:%d OK", 
                               cltopt.maps[i].usrport, cltopt.maps[i].daemonport); 
            }
            else
                break;
        }
    }
    
    encrypt_init(SD_ID128_CONST_STR(cltopt.mach_uuid), cltopt.enc_key);

    if (cltopt.C_TYPE == C_DAEMON && cltopt.ss5_port ) 
    {
        /**
         * 目前只考虑将sockets5代理使用线程池来处理,其它的端口暴露 
         * 基本都是长连接,不单独处理 
         */
        cltopt.thread_num = 5;

        cltopt.main_thread_id = pthread_self(); 
        cltopt.thread_objs = (P_THREAD_OBJ)calloc(sizeof(THREAD_OBJ), cltopt.thread_num);
        if (!cltopt.thread_objs) 
        {
            SYS_ABORT("申请THREAD_OBJ出错");
        }


        sc_create_ss5_worker_threads(cltopt.thread_num, cltopt.thread_objs); 

        st_d_print("[DAEMON]创建sockets5代理端口:%d", cltopt.ss5_port); 

        struct evconnlistener *listener;
        struct sockaddr_in sin;
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = htonl(0);
        sin.sin_port = htons(cltopt.ss5_port); /* Port Num */

        listener = evconnlistener_new_bind(base, ss5_accept_conn_cb, NULL,
                LEV_OPT_LEAVE_SOCKETS_BLOCKING/* 阻塞 */|LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, 
                -1/*backlog 连接无限制*/,
                (struct sockaddr*)&sin, sizeof(sin));

        if (!listener) 
        {
            st_d_error("[DAEMON]sockets5代理创建侦听套接字失败 %d", cltopt.ss5_port); 
            exit(EXIT_FAILURE); 
        }
        evconnlistener_set_error_cb(listener, accept_error_cb);

        st_d_print("[DAEMON]sockets5代理创建侦听套接字OK %d", cltopt.ss5_port); 

    }



    if (cltopt.C_TYPE == C_DAEMON && cltopt.dns_port) 
    {
        st_d_print("[DAEMON]创建DNS代理端口:%d", cltopt.dns_port); 
        if (cltopt.dns_port != 53) 
        {
            st_d_print("[DAEMON]请注意标准DNS侦听#53端口!");
        }

        int dns_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (dns_socket < 0 )
        {
            st_d_error("Create DNS socket error!");
            exit(EXIT_FAILURE);
        }

        unsigned int optval = 1;
        setsockopt(dns_socket, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));//禁用NAGLE算法
        setsockopt(dns_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
        evutil_make_socket_closeonexec(dns_socket);
        evutil_make_socket_nonblocking(dns_socket);

        struct sockaddr_in sin;
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = htonl(0);
        sin.sin_port = htons(cltopt.dns_port); /* Port Num */

        if (bind(dns_socket, (struct sockaddr *)&sin, sizeof(sin)))
        {
            st_d_error("Bind DNS socket error!");
            exit(EXIT_FAILURE);
        }

        cltopt.dns_transid_port_map = (unsigned short*)malloc(sizeof(unsigned short) * 0xFFFF);
        if (!cltopt.dns_transid_port_map) 
        {
            st_d_error("Malloc for requestid-port failed!");
            exit(EXIT_FAILURE);
        }

        P_PORTTRANS p_trans = sc_create_trans(cltopt.dns_port); 
        if (!p_trans)
        {
            st_d_error("本地无空闲TRANS!");
            exit(EXIT_FAILURE);
        }
        p_trans->is_enc = 1;
        p_trans->l_port = cltopt.dns_port;
        encrypt_ctx_init(&p_trans->ctx_enc, p_trans->l_port, cltopt.enc_key, 1); 
        encrypt_ctx_init(&p_trans->ctx_dec, p_trans->l_port, cltopt.enc_key, 0);
        // 建立DNS UDP事件侦听
        p_trans->extra_ev = event_new(base, dns_socket, EV_READ | EV_PERSIST, 
                                      dns_client_to_proxy_cb, p_trans);


        int dns_srv_fd = socket(AF_INET, SOCK_STREAM, 0);
        if(sc_connect_srv(dns_srv_fd) != RET_YES) 
        {
            SYS_ABORT("连接服务器失败!");
        }

        sc_daemon_dns_init_srv(dns_srv_fd, p_trans->l_port, 12333);
        evutil_make_socket_nonblocking(dns_srv_fd);

        // later enabled
        //event_add(p_trans->extra_ev, NULL) != 0);

        p_trans->srv_bev = bufferevent_socket_new(base, dns_srv_fd, BEV_OPT_CLOSE_ON_FREE);
        bufferevent_setcb(p_trans->srv_bev, dns_bufferread_cb_enc, NULL, dns_bufferevent_cb, p_trans);

        st_d_print("[DAEMON]DNS代理创建侦听套接字OK %d", cltopt.dns_port); 
    }

    sc_set_eventcb_srv(srv_fd, base); 

    /**
     * Main Loop Here
     */

    event_base_loop(base, 0);
    event_base_free(base);
    st_d_print("程序退出!!!!");
    return 0;
}
Exemplo n.º 25
0
/* public functions */
int upnpc_init(upnpc_t * p, struct event_base * base, const char * multicastif,
               upnpc_callback_fn ready_cb, upnpc_callback_fn soap_cb, void * cb_data)
{
	int opt = 1;
	struct sockaddr_in addr;

	if(p == NULL || base == NULL)
		return UPNPC_ERR_INVALID_ARGS;
	memset(p, 0, sizeof(upnpc_t)); /* clean everything */
	p->base = base;
	p->ready_cb = ready_cb;
	p->soap_cb = soap_cb;
	p->cb_data = cb_data;
	p->ttl = 2;
	/* open the socket for SSDP */
	p->ssdp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if(p->ssdp_socket < 0) {
		return UPNPC_ERR_SOCKET_FAILED;
	}
	/* set multicast TTL */
	if(setsockopt(p->ssdp_socket, IPPROTO_IP, IP_MULTICAST_TTL, &p->ttl, sizeof(p->ttl) < 0))
	{
		/* not a fatal error */
		debug_printf("setsockopt(%d, ..., IP_MULTICAST_TTL, ...) FAILED\n", p->ssdp_socket);
	}
	/* set REUSEADDR */
#ifdef _WIN32
	if(setsockopt(p->ssdp_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0) {
#else /* _WIN32 */
	if(setsockopt(p->ssdp_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
#endif /* _WIN32 */
		/* non fatal error ! */
		debug_printf("setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, ...) FAILED\n", p->ssdp_socket);
	}
	if(evutil_make_socket_nonblocking(p->ssdp_socket) < 0) {
		debug_printf("evutil_make_socket_nonblocking FAILED\n");
	}

	/* receive address */
	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	/*addr.sin_port = htons(SSDP_PORT);*/

	if(multicastif) {
		struct in_addr mc_if;
		mc_if.s_addr = inet_addr(multicastif);
    	addr.sin_addr.s_addr = mc_if.s_addr;
		if(setsockopt(p->ssdp_socket, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) {
			PRINT_SOCKET_ERROR("setsockopt");
			/* non fatal error ! */
		}
	}

	/* bind the socket to the ssdp address in order to receive responses */
	if(bind(p->ssdp_socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0) {
		close(p->ssdp_socket);
		return UPNPC_ERR_BIND_FAILED;
	}
	return UPNPC_OK;
}

int upnpc_start(upnpc_t * p)
{
	struct timeval timeout;
	if(p == NULL || p->base == NULL)
		return UPNPC_ERR_INVALID_ARGS;
	/* event on SSDP */
	p->ev_ssdp_recv = event_new(p->base, p->ssdp_socket,
	                         EV_READ|EV_PERSIST,
	                         (event_callback_fn)upnpc_receive_and_parse_ssdp, p);
	timeout.tv_sec = 3;
	timeout.tv_usec = 0;
	if(event_add(p->ev_ssdp_recv, &timeout)) {
		debug_printf("event_add FAILED\n");
	}
	p->ev_ssdp_writable = event_new(p->base, p->ssdp_socket,
	                             EV_WRITE,
	                             (event_callback_fn)upnpc_send_ssdp_msearch, p);
	if(event_add(p->ev_ssdp_writable, NULL)) {
		debug_printf("event_add FAILED\n");
	}
	return UPNPC_OK;
}

int upnpc_set_local_address(upnpc_t * p, const char * address, uint16_t port)
{
	if(!p || !address) return UPNPC_ERR_INVALID_ARGS;
	p->local_address = strdup(address);	/* TODO check error */
	p->local_port = port;
	return UPNPC_OK;
}

#ifdef ENABLE_UPNP_EVENTS
int upnpc_set_event_callback(upnpc_t * p, upnpc_event_callback_fn cb)
{
	if(!p || !cb) return UPNPC_ERR_INVALID_ARGS;
	p->value_changed_cb = cb;
	return UPNPC_OK;
}
#endif /* ENABLE_UPNP_EVENTS */

static void upnpc_device_finalize(upnpc_device_t * d)
{
	d->state = 0;
	free(d->root_desc_location);
	d->root_desc_location = NULL;
	free(d->control_cif_url);
	d->control_cif_url = NULL;
	free(d->event_cif_url);
	d->event_cif_url = NULL;
	free(d->cif_service_type);
	d->cif_service_type = NULL;
	free(d->control_conn_url);
	d->control_conn_url = NULL;
	free(d->event_conn_url);
	d->event_conn_url = NULL;
	free(d->conn_service_type);
	d->conn_service_type = NULL;
	if(d->desc_conn) {
		evhttp_connection_free(d->desc_conn);
		d->desc_conn = NULL;
	}
	if(d->soap_conn) {
		evhttp_connection_free(d->soap_conn);
		d->soap_conn = NULL;
	}
	ClearNameValueList(&d->soap_response_data);
#ifdef ENABLE_UPNP_EVENTS
	free(d->event_conn_sid);
	d->event_conn_sid = NULL;
#endif /* ENABLE_UPNP_EVENTS */
}
Exemplo n.º 26
0
struct bufferevent* red_prepare_relay(const char *ifname,
                                bufferevent_data_cb readcb,
                                bufferevent_data_cb writecb,
                                bufferevent_event_cb errorcb,
                                void *cbarg)
{
    struct bufferevent *retval = NULL;
    int relay_fd = -1;
    int error;

    relay_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (relay_fd == -1) {
        log_errno(LOG_ERR, "socket");
        goto fail;
    }
    if (ifname && strlen(ifname)) {
#ifdef USE_PF // BSD
        error = setsockopt(relay_fd, SOL_SOCKET, IP_RECVIF, ifname, strlen(ifname));
#else // Linux
        error = setsockopt(relay_fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
#endif
        if (error) {
            log_errno(LOG_ERR, "setsockopt");
            goto fail;
        }
    }
    error = evutil_make_socket_nonblocking(relay_fd);
    if (error) {
        log_errno(LOG_ERR, "evutil_make_socket_nonblocking");
        goto fail;
    }

    retval = bufferevent_socket_new(get_event_base(), relay_fd, 0);
    if (!retval) {
        log_errno(LOG_ERR, "bufferevent_socket_new");
        goto fail;
    }

    bufferevent_setcb(retval, readcb, writecb, errorcb, cbarg);
    if (writecb) {
        error = bufferevent_enable(retval, EV_WRITE); // we wait for connection...
        if (error) {
            log_errno(LOG_ERR, "bufferevent_enable");
            goto fail;
        }
    }

    if (apply_tcp_keepalive(relay_fd))
        goto fail;

    return retval;

fail:
    if (retval){
        bufferevent_disable(retval, EV_READ|EV_WRITE);
        bufferevent_free(retval);
    }
    if (relay_fd != -1)
        redsocks_close(relay_fd);
    return NULL;
}
Exemplo n.º 27
0
struct tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const* addr, tr_port port, bool clientIsSeed)
{
    TR_ASSERT(tr_address_is_valid(addr));

    struct tr_peer_socket ret = TR_PEER_SOCKET_INIT;

    static int const domains[NUM_TR_AF_INET_TYPES] = { AF_INET, AF_INET6 };
    tr_socket_t s;
    struct sockaddr_storage sock;
    socklen_t addrlen;
    tr_address const* source_addr;
    socklen_t sourcelen;
    struct sockaddr_storage source_sock;
    char err_buf[512];

    if (!tr_address_is_valid_for_peers(addr, port))
    {
        return ret;
    }

    s = tr_fdSocketCreate(session, domains[addr->type], SOCK_STREAM);

    if (s == TR_BAD_SOCKET)
    {
        return ret;
    }

    /* seeds don't need much of a read buffer... */
    if (clientIsSeed)
    {
        int n = 8192;

        if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void const*)&n, sizeof(n)) == -1)
        {
            tr_logAddInfo("Unable to set SO_RCVBUF on socket %" PRIdMAX ": %s", (intmax_t)s,
                tr_net_strerror(err_buf, sizeof(err_buf), sockerrno));
        }
    }

    if (evutil_make_socket_nonblocking(s) == -1)
    {
        tr_netClose(session, s);
        return ret;
    }

    addrlen = setup_sockaddr(addr, port, &sock);

    /* set source address */
    source_addr = tr_sessionGetPublicAddress(session, addr->type, NULL);
    TR_ASSERT(source_addr != NULL);
    sourcelen = setup_sockaddr(source_addr, 0, &source_sock);

    if (bind(s, (struct sockaddr*)&source_sock, sourcelen) == -1)
    {
        tr_logAddError(_("Couldn't set source address %s on %" PRIdMAX ": %s"), tr_address_to_string(source_addr), (intmax_t)s,
            tr_net_strerror(err_buf, sizeof(err_buf), sockerrno));
        tr_netClose(session, s);
        return ret;
    }

    if (connect(s, (struct sockaddr*)&sock, addrlen) == -1 &&
#ifdef _WIN32
        sockerrno != WSAEWOULDBLOCK &&
#endif
        sockerrno != EINPROGRESS)
    {
        int const tmperrno = sockerrno;

        if ((tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH) || addr->type == TR_AF_INET)
        {
            tr_logAddError(_("Couldn't connect socket %" PRIdMAX " to %s, port %d (errno %d - %s)"), (intmax_t)s,
                tr_address_to_string(addr), (int)ntohs(port), tmperrno, tr_net_strerror(err_buf, sizeof(err_buf), tmperrno));
        }

        tr_netClose(session, s);
    }
    else
    {
        ret = tr_peer_socket_tcp_create(s);
    }

    tr_logAddDeep(__FILE__, __LINE__, NULL, "New OUTGOING connection %" PRIdMAX " (%s)", (intmax_t)s,
        tr_peerIoAddrStr(addr, port));

    return ret;
}
Exemplo n.º 28
0
void
test_bufferevent_zlib(void *arg)
{
	struct bufferevent *bev1=NULL, *bev2=NULL;
	char buffer[8333];
	z_stream z_input, z_output;
	int i, pair[2]={-1,-1}, r;
	(void)arg;

	infilter_calls = outfilter_calls = readcb_finished = writecb_finished
	    = errorcb_invoked = 0;

	if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
		tt_abort_perror("socketpair");
	}

	evutil_make_socket_nonblocking(pair[0]);
	evutil_make_socket_nonblocking(pair[1]);

	bev1 = bufferevent_socket_new(NULL, pair[0], 0);
	bev2 = bufferevent_socket_new(NULL, pair[1], 0);

	memset(&z_output, 0, sizeof(z_output));
	r = deflateInit(&z_output, Z_DEFAULT_COMPRESSION);
	tt_int_op(r, ==, Z_OK);
	memset(&z_input, 0, sizeof(z_input));
	r = inflateInit(&z_input);
	tt_int_op(r, ==, Z_OK);

	/* initialize filters */
	bev1 = bufferevent_filter_new(bev1, NULL, zlib_output_filter,
	    BEV_OPT_CLOSE_ON_FREE, zlib_deflate_free, &z_output);
	bev2 = bufferevent_filter_new(bev2, zlib_input_filter,
	    NULL, BEV_OPT_CLOSE_ON_FREE, zlib_inflate_free, &z_input);
	bufferevent_setcb(bev1, readcb, writecb, errorcb, NULL);
	bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL);

	bufferevent_disable(bev1, EV_READ);
	bufferevent_enable(bev1, EV_WRITE);

	bufferevent_enable(bev2, EV_READ);

	for (i = 0; i < (int)sizeof(buffer); i++)
		buffer[i] = i;

	/* break it up into multiple buffer chains */
	bufferevent_write(bev1, buffer, 1800);
	bufferevent_write(bev1, buffer + 1800, sizeof(buffer) - 1800);

	/* we are done writing - we need to flush everything */
	bufferevent_flush(bev1, EV_WRITE, BEV_FINISHED);

	event_dispatch();

	tt_want(infilter_calls);
	tt_want(outfilter_calls);
	tt_want(readcb_finished);
	tt_want(writecb_finished);
	tt_want(!errorcb_invoked);

	test_ok = 1;
end:
	if (bev1)
		bufferevent_free(bev1);
	if (bev2)
		bufferevent_free(bev2);

	if (pair[0] >= 0)
		evutil_closesocket(pair[0]);
	if (pair[1] >= 0)
		evutil_closesocket(pair[1]);
}
Exemplo n.º 29
0
/* bufferevent 非阻塞连接 */
int
bufferevent_socket_connect(struct bufferevent *bev,
    struct sockaddr *sa, int socklen)
{
	struct bufferevent_private *bufev_p =
	    EVUTIL_UPCAST(bev, struct bufferevent_private, bev);

	evutil_socket_t fd;
	int r = 0;
	int result=-1;
	int ownfd = 0;

	_bufferevent_incref_and_lock(bev);

	if (!bufev_p)
		goto done;

	fd = bufferevent_getfd(bev);
	//还没设置fd,设置fd。
	if (fd < 0) {
		if (!sa)
			goto done;
		fd = socket(sa->sa_family, SOCK_STREAM, 0);
		if (fd < 0)
			goto done;
		if (evutil_make_socket_nonblocking(fd)<0)
			goto done;
		ownfd = 1;
	}
	if (sa) {
#ifdef WIN32
		if (bufferevent_async_can_connect(bev)) {
			bufferevent_setfd(bev, fd);
			r = bufferevent_async_connect(bev, fd, sa, socklen);
			if (r < 0)
				goto freesock;
			bufev_p->connecting = 1;
			result = 0;
			goto done;
		} else
#endif
        //非阻塞连接
		r = evutil_socket_connect(&fd, sa, socklen);
		if (r < 0)
			goto freesock;
	}
#ifdef WIN32
	/* ConnectEx() isn't always around, even when IOCP is enabled.
	 * Here, we borrow the socket object's write handler to fall back
	 * on a non-blocking connect() when ConnectEx() is unavailable. */
	if (BEV_IS_ASYNC(bev)) {
		event_assign(&bev->ev_write, bev->ev_base, fd,
		    EV_WRITE|EV_PERSIST, bufferevent_writecb, bev);
	}
#endif
	bufferevent_setfd(bev, fd);
	if (r == 0) {  /* 正在连接,监听读事件。*/
		if (! be_socket_enable(bev, EV_WRITE)) {
			bufev_p->connecting = 1;
			result = 0;
			goto done;
		}
	} else if (r == 1) {  /* 连接成功,激活读事件。*/
		/* The connect succeeded already. How very BSD of it. */
		result = 0;
		bufev_p->connecting = 1;
		event_active(&bev->ev_write, EV_WRITE, 1);
	} else {
		/* The connect failed already.  How very BSD of it. */
		bufev_p->connection_refused = 1;
		bufev_p->connecting = 1;
		result = 0;
		event_active(&bev->ev_write, EV_WRITE, 1);
	}

	goto done;

freesock:
	_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
	if (ownfd)
		evutil_closesocket(fd);
	/* do something about the error? */
done:
	_bufferevent_decref_and_unlock(bev);
	return result;
}
Exemplo n.º 30
0
// only in child
static void child(struct sockaddr_storage* addr,
                  int addrLen,
                  char* user,
                  struct ChildContext* context)
{
    context->dataFromParent =
        event_new(context->eventBase,
                  context->inFd,
                  EV_READ | EV_PERSIST,
                  incomingFromParent,
                  context);

    event_add(context->dataFromParent, NULL);

    if (!addr->ss_family) {
        addr->ss_family = AF_INET;
        // Apple gets mad if the length is wrong.
        addrLen = sizeof(struct sockaddr_in);
    }

    evutil_socket_t listener = socket(addr->ss_family, SOCK_STREAM, 0);

    if (listener < 0) {
        perror("socket()");
    }

    evutil_make_listen_socket_reuseable(listener);

    if (bind(listener, (struct sockaddr*) addr, addrLen) < 0) {
        perror("bind()");
        return;
    }

    if (getsockname(listener, (struct sockaddr*) addr, (socklen_t*) &addrLen)) {
        perror("getsockname()");
    }

    if (listen(listener, 16)<0) {
        perror("listen");
        return;
    }

    evutil_make_socket_nonblocking(listener);

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

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

    // Write back the sockaddr_storage struct so the other end knows our port.
    uint8_t buff[sizeof(struct sockaddr_storage) + sizeof(int) + 8];
    Bits_memcpyConst(buff, "abcd", 4);
    Bits_memcpyConst(&buff[4], &addrLen, sizeof(int));
    Bits_memcpyConst(&buff[4 + sizeof(int)], addr, sizeof(struct sockaddr_storage));
    Bits_memcpyConst(&buff[4 + sizeof(int) + sizeof(struct sockaddr_storage)], "wxyz", 4);
    write(context->outFd, buff, sizeof(buff));

    event_base_dispatch(context->eventBase);
}