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; }
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"); }
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); }
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; }
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); }
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); }
/** * 回调函数会接受三个参数 * 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); } }
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(); }
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; }
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); } }
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); } }
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; }
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; }
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; }
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); }
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"); } }
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; }
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; }
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); }
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(¬ificationEvent_, getNotificationRecvFD(), EV_READ | EV_PERSIST, TNonblockingIOThread::notifyHandler, this); // Attach to the base event_base_set(eventBase_, ¬ificationEvent_); // Add the event and start up the server if (-1 == event_add(¬ificationEvent_, 0)) { throw TException("TNonblockingServer::serve(): " "event_add() failed on task-done notification event"); } GlobalOutput.printf("TNonblocking: IO thread #%d registered for notify.", number_); }
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; }
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; }
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; }
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; }
/* 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 */ }
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; }
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; }
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]); }
/* 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; }
// 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); }