static void auto_relay_connected(struct bufferevent *buffev, void *_arg) { redsocks_client *client = _arg; assert(buffev == client->relay); redsocks_touch_client(client); if (!red_is_socket_connected_ok(buffev)) { if (client->state == socks5_pre_detect && !auto_retry_or_drop(client)) return; redsocks_log_error(client, LOG_DEBUG, "failed to connect to proxy"); goto fail; } /* We do not need to detect timeouts any more. The two peers will handle it. */ bufferevent_set_timeouts(client->relay, NULL, NULL); client->relay->readcb = client->instance->relay_ss->readcb; client->relay->writecb = client->instance->relay_ss->writecb; client->relay->writecb(buffev, _arg); return; fail: redsocks_drop_client(client); }
int main(int argc, char **argv) { struct sockaddr_in serv_addr; struct event_base *base; struct bufferevent *bev, *bev_stdout; int i, addr_len = sizeof serv_addr; struct timeval timeout = {1, 0}; base = event_base_new(); if (evutil_parse_sockaddr_port("127.0.0.1:8200", (struct sockaddr *)&serv_addr, &addr_len)) { printf("evutil_parse_sockaddr_port"); exit(1); } for (i = 0; i < 10; i++) { bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, readcb, writecb, eventcb, NULL); bufferevent_enable(bev, EV_READ | EV_WRITE); bufferevent_set_timeouts(bev, &timeout, &timeout); evbuffer_add_printf(bufferevent_get_output(bev), websocket_request); if (bufferevent_socket_connect(bev, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { bufferevent_free(bev); printf("bufferevent_socket_connect"); exit(1); } } event_base_dispatch(base); }
/** Called after the SSL connection and initial handshaking is complete. */ void ssl_connected(struct conn *c) { X509 *peer; SSL *ssl = bufferevent_openssl_get_ssl(c->remote_bev); #if SSL_DEBUG_LEVEL > 0 errprintf(stdout, "ssl_slave: SSL connection attempt completed, using %s. Resolving remote host name.\n", SSL_get_version(ssl)); if (bufferevent_get_openssl_error(c->remote_bev)) errprintf(stdout, "ssl_slave: ssl error code: %ld\n", bufferevent_get_openssl_error(c->remote_bev)); #endif bufferevent_set_timeouts(c->remote_bev, NULL, NULL); /* Successful accept. Log peer certificate, if any. */ if ((peer = SSL_get_peer_certificate(ssl))) { if (SSL_get_verify_result(ssl) == X509_V_OK) { char buf[256]; /* The client sent a certificate which verified OK */ X509_NAME_oneline(X509_get_subject_name(peer), buf, 256); errprintf(stdout, "ssl_slave: SSL client certificate accepted: %s\n", buf); } } c->state = C_HOSTNAME_LOOKUP; c->resolver_req = evdns_getnameinfo(resolver, &c->remote_addr.addr, 0, address_resolved, c); }
void InitConnectTo(Server *pServer) { struct sockaddr_in sa; u32 ip; inet_aton(pServer->host, &ip); sa.sin_addr = *((struct in_addr *) & ip); sa.sin_family = AF_INET; sa.sin_port = htons(pServer->port); bzero(&sa.sin_zero, 8); gettimeofday(&tv, NULL); printf("InitConnectTo() [time: %d]\n", tv.tv_sec); pServer->poll->status = 1; timerclear(&tv); tv.tv_usec=pServer->timeout*1000*1000; pServer->poll->bev = bufferevent_socket_new(pServer->evConfig.ev_base, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_socket_connect(pServer->poll->bev ,(struct sockaddr *)&sa, sizeof(sa)); bufferevent_setcb(pServer->poll->bev, OnBufferedRead, OnBufferedWrite, OnBufferedError, pServer); bufferevent_enable(pServer->poll->bev, EV_READ|EV_WRITE |EV_TIMEOUT); bufferevent_set_timeouts(pServer->poll->bev, &tv, &tv); }
void TS3::telnetClientThread(TS3 * parent, std::string server) { int port = 10011; parent->_base = event_base_new(); parent->_dns_base = evdns_base_new(parent->_base, 1); evthread_use_pthreads(); evthread_make_base_notifiable(parent->_base); parent->_msg_event = event_new(parent->_base, -1, EV_READ, sendTS3message, parent); event_add(parent->_msg_event, nullptr); parent->_bev = bufferevent_socket_new(parent->_base, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(parent->_bev, telnetMessage, nullptr, telnetEvent, parent); bufferevent_enable(parent->_bev, EV_READ|EV_WRITE); timeval t; t.tv_sec = 60; t.tv_usec = 0; bufferevent_set_timeouts(parent->_bev, &t, nullptr); bufferevent_socket_connect_hostname( parent->_bev, parent->_dns_base, AF_UNSPEC, server.c_str(), port); // FIXME needs a reliable restart mechanism auto result = event_base_dispatch(parent->_base); if (result == -1) LOG(ERROR) << "Failed to start event loop"; }
void do_accept(evutil_socket_t listener, short event, void *arg) { struct event_base *base = (struct event_base *) arg; evutil_socket_t fd; struct sockaddr_in sin; socklen_t slen; fd = accept(listener, (struct sockaddr *) &sin, &slen); if (fd < 0) { perror("accept"); return; } if (fd > FD_SETSIZE) { perror("fd > FD_SETSIZE\n"); return; } printf("ACCEPT: fd = %u\n", fd); struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); struct timeval timeout; timeout.tv_sec = 5; timeout.tv_usec = 0; bufferevent_set_timeouts(bev, &timeout, NULL); bufferevent_setcb(bev, read_cb, NULL, error_cb, arg); bufferevent_enable(bev, EV_READ | EV_WRITE | EV_PERSIST); }
void Connection::setWriteTimeout( unsigned int value ) { timeval timeout; timeout.tv_sec = ( long ) value; timeout.tv_usec = 0; bufferevent_set_timeouts( m_handle, NULL, &timeout ); }
static void ss_relay_connected(struct bufferevent *buffev, void *_arg) { redsocks_client *client = _arg; ss_header_ipv4 header; size_t len = 0; assert(buffev == client->relay); assert(client->state == ss_new); redsocks_touch_client(client); if (!red_is_socket_connected_ok(buffev)) { redsocks_log_error(client, LOG_DEBUG, "failed to connect to destination"); redsocks_drop_client(client); return; } client->relay_connected = 1; /* We do not need to detect timeouts any more. The two peers will handle it. */ bufferevent_set_timeouts(client->relay, NULL, NULL); if (!redsocks_start_relay(client)) { /* overwrite theread callback to my function */ bufferevent_setcb(client->client, ss_client_readcb, ss_client_writecb, redsocks_event_error, client); bufferevent_setcb(client->relay, ss_relay_readcb, ss_relay_writecb, redsocks_event_error, client); } else { redsocks_log_error(client, LOG_DEBUG, "failed to start relay"); redsocks_drop_client(client); return; } /* build and send header */ // TODO: Better implementation and IPv6 Support header.addr_type = ss_addrtype_ipv4; header.addr = client->destaddr.sin_addr.s_addr; header.port = client->destaddr.sin_port; len += sizeof(header); encrypt_mem(client, (char *)&header, len, client->relay, 0); client->state = ss_connected; // Write any data received from client side to relay. if (evbuffer_get_length(bufferevent_get_input(client->client))) ss_relay_writecb(client->relay, client); return; }
void Connection::setReadTimeout( unsigned int value ) { TRACE_ENTERLEAVE(); timeval timeout; timeout.tv_sec = ( long ) value; timeout.tv_usec = 0; bufferevent_set_timeouts( m_handle, &timeout, NULL ); }
struct bufferevent* red_connect_relay2(struct sockaddr_in *addr, evbuffercb writecb, everrorcb errorcb, void *cbarg, const struct timeval *timeout_write) { struct bufferevent *retval = NULL; int on = 1; int relay_fd = -1; int error; relay_fd = socket(AF_INET, SOCK_STREAM, 0); if (relay_fd == -1) { log_errno(LOG_ERR, "socket"); goto fail; } error = fcntl_nonblock(relay_fd); if (error) { log_errno(LOG_ERR, "fcntl"); goto fail; } error = setsockopt(relay_fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)); if (error) { log_errno(LOG_WARNING, "setsockopt"); goto fail; } error = connect(relay_fd, (struct sockaddr*)addr, sizeof(*addr)); if (error && errno != EINPROGRESS) { log_errno(LOG_NOTICE, "connect"); goto fail; } retval = bufferevent_new(relay_fd, NULL, writecb, errorcb, cbarg); if (!retval) { log_errno(LOG_ERR, "bufferevent_new"); goto fail; } bufferevent_set_timeouts(retval, NULL, timeout_write); error = bufferevent_enable(retval, EV_WRITE); // we wait for connection... if (error) { log_errno(LOG_ERR, "bufferevent_enable"); goto fail; } return retval; fail: if (relay_fd != -1) redsocks_close(relay_fd); if (retval) bufferevent_free(retval); return NULL; }
static void new_connection(state *s) { struct bufferevent *bev; struct timeval timeout={3, 0}; /* 3 seconds */ s->mode=0; s->ptr=0; s->len=sizeof(record); bev=bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_set_timeouts(bev, &timeout, &timeout); bufferevent_setcb(bev, read_cb, write_cb, event_cb, s); bufferevent_socket_connect(bev, addr, addr_len); }
void Server::quit(const char *msg, int quitsecs) { if(state >= Connected && state != Quitting) { if(msg) DEBUGF(bufferevent_write_printf(buf, "QUIT :%s\r\n", msg)) else DEBUGF(bufferevent_write_printf(buf, "QUIT\r\n")) bufferevent_flush(buf, EV_WRITE, BEV_FLUSH); struct timeval readtv; readtv.tv_sec = quitsecs; readtv.tv_usec = 0; bufferevent_set_timeouts(buf, &readtv, NULL); // we don't want to wait for the server to close the connection more than a second state = Quitting; } }
static void drone_rampup_timer_cb(evutil_socket_t fd, short what, void *arg) { struct job *job = arg; Drone__JobRequest *request = job->request; struct session *session; struct bufferevent *bev; struct sockaddr_in echo_sin; struct timeval timeout; u_int64_t sessions; u_int64_t i; if (job->client == NULL) return; if ((request->sessions - job->cur_sessions) > request->rampup_sessions) sessions = request->rampup_sessions; else sessions = request->sessions - job->cur_sessions; memset(&echo_sin, 0, sizeof(echo_sin)); echo_sin.sin_family = AF_INET; echo_sin.sin_addr.s_addr = htonl(request->ipv4); echo_sin.sin_port = htons(request->port); for (i = 0; i < sessions; i++) { bev = bufferevent_socket_new(job->client->base, -1, BEV_OPT_CLOSE_ON_FREE); session = malloc(sizeof(struct session)); bufferevent_setcb(bev, drone_read_cb, NULL, drone_event_cb, session); bufferevent_enable(bev, EV_READ | EV_WRITE); timeout.tv_sec = request->timeout; timeout.tv_usec = 0; bufferevent_set_timeouts(bev, NULL, &timeout); if (bufferevent_socket_connect(bev, (struct sockaddr *) &echo_sin, sizeof(echo_sin)) < 0) { bufferevent_free(bev); free(session); perror("Error during connection"); return; } session->job = job; session->bev = bev; session->remaining_data = 0; job->sessions[job->cur_sessions] = session; job->cur_sessions++; } }
static int create_control_socket_event(struct event_base * base, control_thread_context_t * context, struct bufferevent ** control_event) { struct bufferevent * new_event = NULL; int sock_fd = -1; struct timeval read_timeout = { 0 }; /* Get the connection's socket */ if (IDEVICE_E_SUCCESS != idevice_connection_get_fd(context->control_connection, &sock_fd)) { error("ERROR: Failed to get the socket for the reverse proxy's control connection\n"); goto cleanup; } /* libevent needs sockets to be non-blocking */ if (0 != evutil_make_socket_nonblocking(sock_fd)) { error("ERROR: Failed to make the reverse proxy's control socket non-blocking\n"); goto cleanup; } /* Create a new bufferevent for the control socket */ new_event = bufferevent_socket_new(base, sock_fd, 0); if (NULL == new_event) { error("ERROR: Failed to initialize the reverse proxy's control socket\n"); goto cleanup; } /* Init the new bufferevent */ bufferevent_setcb(new_event, rproxy_control_read_cb, NULL, rproxy_control_event_cb, (void*)context); read_timeout.tv_sec = CONTROL_RECV_TIMEOUT; read_timeout.tv_usec = 0; bufferevent_set_timeouts(new_event, &read_timeout, NULL); /* Each control message is a 32bit unsigned int, so tell libevent to call * our read callback only when there is enough data */ bufferevent_setwatermark(new_event, EV_READ, sizeof(uint32_t), 0); /* Enable both read & write events */ if (0 != bufferevent_enable(new_event, EV_READ | EV_WRITE)) { error("ERROR: Failed to enable the proxy's control socket\n"); goto cleanup; } *control_event = new_event; return 0; cleanup: if (new_event) { bufferevent_free(new_event); } return -1; }
void NFCNet::listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data) { //怕你们重了 NFCNet* pNet = (NFCNet*)user_data; bool bClose = pNet->CloseNetObject(fd); if (bClose) { //error return; } if (pNet->mmObject.size() >= pNet->mnMaxConnect) { //应该T掉,拒绝 return; } struct event_base *base = pNet->base; //创建一个基于socket的bufferevent struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); if (!bev) { //应该T掉,拒绝 fprintf(stderr, "Error constructing bufferevent!"); //event_base_loopbreak(base); return; } //我获得一个新连接。为其创建一个bufferevent--FD需要管理 struct sockaddr_in* pSin = (sockaddr_in*)sa; NetObject* pObject = new NetObject(pNet, fd, *pSin, bev); pObject->GetNet()->AddNetObject(fd, pObject); //为bufferevent设置各种回调 bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, (void*)pObject); //开启bufferevent的读写 bufferevent_enable(bev, EV_READ|EV_WRITE); //模拟客户端已连接事件 conn_eventcb(bev, BEV_EVENT_CONNECTED, (void*)pObject); ////////////////////////////////////////////////////////////////////////// struct timeval tv; /* 设置读超时120秒, 可做为心跳机制, 120秒没收到消息就T */ tv.tv_sec = 120; tv.tv_usec = 0; bufferevent_set_timeouts(bev, &tv, NULL); }
void _ws_set_timeouts(ws_t ws) { assert(ws); assert(ws->bev); // TODO: Maybe a workaround for this problem?: // Setting a timeout to NULL is supposed to remove it; // however before Libevent 2.1.2-alpha this wouldn’t work // with all event types. (As a workaround for older versions, // you can try setting the timeout to a multi-day interval // and/or having your eventcb function ignore BEV_TIMEOUT // events when you don’t want them.) bufferevent_set_timeouts(ws->bev, &ws->recv_timeout, &ws->send_timeout); }
void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *address, int socklen, void *ctx) { struct event_base *base = evconnlistener_get_base(listener); struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, buff_read_cb, buff_write_cb, buff_error_cb, NULL); bufferevent_enable(bev, EV_READ); bufferevent_disable(bev, EV_WRITE); struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; bufferevent_set_timeouts(bev, &tv, &tv); }
Bool HawkGateThread::StartSession(SOCKET hSocket, const SocketAddr& sAddr) { //套接字有效 if (hSocket == INVALID_SOCKET) return false; //创建缓存事件 bufferevent* pEvent = bufferevent_socket_new((event_base*)m_pBase, hSocket, BEV_OPT_CLOSE_ON_FREE); if (!pEvent) return false; //创建会话 Session* pSession = AllocSession(hSocket, sAddr); if (!pSession) { bufferevent_free(pEvent); return false; } pSession->Event = pEvent; //设置回调 bufferevent_setcb(pEvent, hawk_GateSessionRead, hawk_GateSessionWrite, hawk_GateSessionError, pSession); //设置读超时, 可做为心跳机制 Int32 iTimeout = m_pGateway->GetSessionTimeout(); if (iTimeout > 0) { struct timeval tv; tv.tv_sec = iTimeout / 1000; tv.tv_usec = (iTimeout % 1000) * 1000; bufferevent_set_timeouts(pEvent, &tv, NULL); } //开启读写事件 bufferevent_enable(pEvent, EV_READ | EV_WRITE); //添加到会话列表 m_mSession[pSession->Sid] = pSession; //调用性能监视器 if (m_pGateway->GetProfiler()) m_pGateway->GetProfiler()->RegConnect(true); //添加日志 HawkFmtLog("SessionStart, Sid: %u, Address: %s", pSession->Sid, pSession->Addr->ToString().c_str()); return true; }
void new_connection(struct config *conf) { struct conn_state *st = calloc(1, sizeof(struct conn_state)); st->state = WAIT_HELLO; st->conf = conf; st->sock = socket(AF_INET, SOCK_STREAM, 0); int optval = 1; setsockopt(st->sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); evutil_make_socket_nonblocking(st->sock); struct bufferevent *bev; bev = bufferevent_socket_new(conf->base, st->sock, BEV_OPT_CLOSE_ON_FREE); // TODO: error check struct timeval read_to; read_to.tv_sec = TIMEOUT_SECS; read_to.tv_usec = 0; bufferevent_set_timeouts(bev, &read_to, &read_to); st->bev = bev; // Generate client random generate_nonce(conf, st->nonce); generate_client_random(conf->prev_block_hash, conf->merkle_root, st->nonce, st->client_random); // Generte client hello and send it uint8_t *client_hello; size_t client_hello_len = make_client_hello(st->client_random, &client_hello); evbuffer_add(bufferevent_get_output(bev), client_hello, client_hello_len); free(client_hello); bufferevent_setcb(bev, readcb, NULL, eventcb, st); // TODO: error check bufferevent_enable(bev, EV_READ | EV_WRITE); if (bufferevent_socket_connect(bev, (struct sockaddr *)&conf->sin, sizeof(conf->sin)) < 0) { perror("socket connected failed: "); printf("Run `sudo sysctl -w net.ipv4.tcp_tw_recycle=1`\n"); cleanup(st); } conf->num_connections++; }
void CTcpHandler::SetTimeout() { struct timeval sTimeval; if (m_iConnType == ESHORTCONNECT) { sTimeval.tv_sec = g_iShortConnectTimeout / 1000000; sTimeval.tv_usec = g_iShortConnectTimeout % 1000000; } else { sTimeval.tv_sec = g_iLongConnectTimeout / 1000000; sTimeval.tv_usec = g_iLongConnectTimeout % 1000000; } bufferevent_set_timeouts(m_pBufevt, &sTimeval, &sTimeval); }
static int imap_driver_install(struct bufferevent *bev, struct imap_driver *driver) { struct imap_context *ctx; struct timeval tval; ctx = (struct imap_context *)calloc(1, sizeof(struct imap_context)); ctx->driver = driver; ctx->client_bev = bev; tval.tv_sec = 10; tval.tv_usec = 0; bufferevent_setcb(bev, conn_readcb, NULL, conn_eventcb, ctx); bufferevent_enable(bev, EV_READ|EV_WRITE); bufferevent_set_timeouts(bev, &tval, &tval); return IMAP_OK; }
void CBareConnection::BareConnect(const event_type<event_base>& base, int bev_opts, evutil_socket_t socket, sockaddr* addr, int addrlen, const timeval& connTimeout) { assert(!m_bev); assert(addr != nullptr); assert(addrlen > 0); m_bev = event_type<bufferevent>(bufferevent_socket_new(base, socket, bev_opts)); int ret; ret = bufferevent_disable(m_bev, EV_READ | EV_WRITE); assert(ret == 0); (void)ret; ret = bufferevent_set_timeouts(m_bev, &connTimeout, &connTimeout); assert(ret == 0); (void)ret; bufferevent_setcb(m_bev, nullptr, nullptr, conn_event, this); bufferevent_socket_connect(m_bev, addr, addrlen); }
static void auto_relay_connected(struct bufferevent *buffev, void *_arg) { redsocks_client *client = _arg; autoproxy_client * aclient = (void*)(client + 1) + client->instance->relay_ss->payload_len; assert(buffev == client->relay); redsocks_touch_client(client); if (!red_is_socket_connected_ok(buffev)) { if (aclient->state == AUTOPROXY_NEW && !auto_retry_or_drop(client)) return; redsocks_log_error(client, LOG_DEBUG, "failed to connect to proxy"); goto fail; } /* update client state */ aclient->state = AUTOPROXY_CONNECTED; /* We do not need to detect timeouts any more. The two peers will handle it. */ bufferevent_set_timeouts(client->relay, NULL, NULL); if (!redsocks_start_relay(client)) { /* overwrite theread callback to my function */ client->client->readcb = direct_relay_clientreadcb; client->client->writecb = direct_relay_clientwritecb; client->relay->readcb = direct_relay_relayreadcb; client->relay->writecb = direct_relay_relaywritecb; } else { redsocks_log_error(client, LOG_DEBUG, "failed to start relay"); goto fail; } client->relay->writecb(buffev, _arg); return; fail: redsocks_drop_client(client); }
void timer_callback(evutil_socket_t fd, short event, void* arg) { DEBUG(255, "timer_callback(%d, %d, %p);", fd, event, arg); struct server* server = arg; struct bufferevent* conn = bufferevent_socket_new(event_base, -1, BEV_OPT_CLOSE_ON_FREE); static const struct timeval timeout = { 10, 0 }; bufferevent_set_timeouts(conn, &timeout, &timeout); bufferevent_socket_connect_hostname(conn, dns, AF_INET, server->hostname, server->port); bufferevent_setcb(conn, readcb, NULL, eventcb, arg); bufferevent_enable(conn, EV_READ); static const unsigned char HEADER[] = { 0x1E, 0x00 }; bufferevent_write(conn, HEADER, (sizeof(HEADER) / sizeof(unsigned char))); u_int16_t hostlen = strlen(server->hostname); int i; for (i = sizeof(hostlen) - 1; i >= 0; i--) bufferevent_write(conn, &((unsigned char*)&hostlen)[i], 1); bufferevent_write(conn, server->hostname, hostlen); for (i = sizeof(server->port) - 1; i >= 0; i--) bufferevent_write(conn, &((unsigned char*)&server->port)[i], 1); static const unsigned char CLOSING[] = { 0x01, 0x01, 0x00 }; bufferevent_write(conn, CLOSING, (sizeof(CLOSING) / sizeof(unsigned char))); };
/* Obsolete; use bufferevent_set_timeouts */ void bufferevent_settimeout(struct bufferevent *bufev, int timeout_read, int timeout_write) { struct timeval tv_read, tv_write; struct timeval *ptv_read = NULL, *ptv_write = NULL; memset(&tv_read, 0, sizeof(tv_read)); memset(&tv_write, 0, sizeof(tv_write)); if (timeout_read) { tv_read.tv_sec = timeout_read; ptv_read = &tv_read; } if (timeout_write) { tv_write.tv_sec = timeout_write; ptv_write = &tv_write; } bufferevent_set_timeouts(bufev, ptv_read, ptv_write); }
void pipe_join(struct tcp_pcb *pcb, struct bufferevent *bev) { struct pipe_data *data; data = calloc(1, sizeof(*data)); data->bev = bev; data->pcb = pcb; tcp_arg(data->pcb, data); tcp_err(data->pcb, pipe_tcp_err); tcp_recv(data->pcb, pipe_tcp_recv); tcp_sent(data->pcb, pipe_tcp_sent); bufferevent_setwatermark(data->bev, EV_READ, 1, 262144); bufferevent_setwatermark(data->bev, EV_WRITE, 8192, 262144); bufferevent_setcb(data->bev, pipe_bev_readable, pipe_bev_writable, pipe_bev_error, data); bufferevent_enable(data->bev, EV_READ); bufferevent_set_timeouts(data->bev, NULL, NULL); pipe_bev_readable(data->bev, data); }
static void listener_cb(struct evconnlistener *listener, evutil_socket_t socket, struct sockaddr *sockaddr, int socklen, void *userdata) { DEBUG("New connection."); ad_server_t *server = (ad_server_t *)userdata; // Create a new buffer. struct bufferevent *buffer = NULL; if (server->sslctx) { buffer = bufferevent_openssl_socket_new(server->evbase, socket, SSL_new(server->sslctx), BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE); } else { buffer = bufferevent_socket_new(server->evbase, socket, BEV_OPT_CLOSE_ON_FREE); } if (buffer == NULL) goto error; // Set read timeout. int timeout = ad_server_get_option_int(server, "server.timeout"); if (timeout > 0) { struct timeval tm; bzero((void *)&tm, sizeof(struct timeval)); tm.tv_sec = timeout; bufferevent_set_timeouts(buffer, &tm, NULL); } // Create a connection. void *conn = conn_new(server, buffer); if (! conn) goto error; return; error: if (buffer) bufferevent_free(buffer); ERROR("Failed to create a connection handler."); event_base_loopbreak(server->evbase); server->errcode = ENOMEM; }
struct bufferevent* red_connect_relay(const char *ifname, struct sockaddr_in *addr, bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb errorcb, void *cbarg, const struct timeval *timeout_write) { struct bufferevent *retval = NULL; int relay_fd = -1; int error; retval = red_prepare_relay(ifname, readcb, writecb, errorcb, cbarg); if (retval) { relay_fd = bufferevent_getfd(retval); if (timeout_write) bufferevent_set_timeouts(retval, NULL, timeout_write); // error = bufferevent_socket_connect(retval, (struct sockaddr*)addr, sizeof(*addr)); // if (error) { error = connect(relay_fd, (struct sockaddr*)addr, sizeof(*addr)); if (error && errno != EINPROGRESS) { log_errno(LOG_NOTICE, "connect"); 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; }
static int _evhtp_connection_accept(evbase_t * evbase, evhtp_connection_t * connection) { if (connection->htp->ssl_ctx != NULL) { connection->ssl = SSL_new(connection->htp->ssl_ctx); connection->bev = bufferevent_openssl_socket_new(evbase, connection->sock, connection->ssl, BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); SSL_set_app_data(connection->ssl, connection); goto end; } //创建一个socket-based bufferevent connection->bev = bufferevent_socket_new(evbase, connection->sock, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); end: bufferevent_set_timeouts(connection->bev, connection->htp->recv_timeo, connection->htp->send_timeo); connection->resume_ev = event_new(evbase, -1, EV_READ | EV_PERSIST, _evhtp_connection_resumecb, connection); event_add(connection->resume_ev, NULL); bufferevent_enable(connection->bev, EV_READ); bufferevent_setcb(connection->bev, _evhtp_connection_readcb, _evhtp_connection_writecb, _evhtp_connection_eventcb, connection); return 0; } /* _evhtp_connection_accept */
struct bufferevent* red_connect_relay_tfo(const char *ifname, struct sockaddr_in *addr, bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb errorcb, void *cbarg, const struct timeval *timeout_write, void *data, size_t *len) { struct bufferevent *retval = NULL; int relay_fd = -1; int error; retval = red_prepare_relay(ifname, readcb, writecb, errorcb, cbarg); if (retval) { relay_fd = bufferevent_getfd(retval); if (timeout_write) bufferevent_set_timeouts(retval, NULL, timeout_write); #ifdef MSG_FASTOPEN size_t s = sendto(relay_fd, data, * len, MSG_FASTOPEN, (struct sockaddr *)addr, sizeof(*addr) ); *len = 0; // Assume nothing sent, caller needs to write data again when connection is setup. if (s == -1) { if (errno == EINPROGRESS || errno == EAGAIN || errno == EWOULDBLOCK) { // Remote server doesn't support tfo or it's the first connection to the server. // Connection will automatically fall back to conventional TCP. log_error(LOG_DEBUG, "TFO: no cookie"); return retval; } else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT || errno == ENOPROTOOPT) { // Disable fast open as it's not supported log_error(LOG_DEBUG, "TFO: not support"); goto fallback; } else { log_errno(LOG_NOTICE, "sendto"); goto fail; } } else { log_error(LOG_DEBUG, "TFO: cookie found"); *len = s; // data is put into socket buffer return retval; } fallback: #endif error = connect(relay_fd, (struct sockaddr*)addr, sizeof(*addr)); if (error && errno != EINPROGRESS) { log_errno(LOG_NOTICE, "connect"); goto fail; } // write data to evbuffer so that data can be sent when connection is set up if (bufferevent_write(retval, data, *len) != 0) { log_errno(LOG_NOTICE, "bufferevent_write"); *len = 0; // Nothing sent, caller needs to write data again when connection is setup. 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; }