void error_cb(struct bufferevent *bev, short event, void *arg) { evutil_socket_t fd = bufferevent_getfd(bev); printf("fd = %u, ", fd); if (event & BEV_EVENT_TIMEOUT) { printf("Timed out\n"); //if bufferevent_set_timeouts() called } else if (event & BEV_EVENT_EOF) { printf("connection closed\n"); } else if (event & BEV_EVENT_ERROR) { printf("some other error\n"); } bufferevent_free(bev); }
/* 事件回调函数,连接状态改变时回调的函数 */ void event_cb(struct bufferevent *bev, short events, void *ptr) { struct event_base *tbase = (struct event_base*)ptr; if ( events & BEV_EVENT_CONNECTED){ /* We're connected to server. Ordinarily we'd do something here, like start reading or writing. */ evutil_socket_t fd = bufferevent_getfd(bev); set_tcp_no_delay(fd); printf("Server is connected!\n"); }else { //如果连接不成功的消息,就停止事件循环 bufferevent_free(bev); event_base_loopbreak(tbase); printf("Server connect erro!! or The connect have been shutdown: %X\n", events); } }
void listencb(struct evconnlistener *listener, evutil_socket_t clisockfd, struct sockaddr *addr, int len, void *ptr) { struct event_base *eb = evconnlistener_get_base(listener); struct bufferevent *bev = bufferevent_socket_new(eb, clisockfd, BEV_OPT_CLOSE_ON_FREE); LOG("a user logined in, socketfd = %d", bufferevent_getfd(bev)); //create a user user_t *user = user_create(); user->wscon->bev = bev; user_vec.push_back(user); //ws_conn_setcb(wscon, HANDSHAKE, testfunc, (void*)"haha"); ws_conn_setcb(user->wscon, FRAME_RECV, frame_recv_cb, user); ws_conn_setcb(user->wscon, CLOSE, user_disconnect_cb, user); ws_serve_start(user->wscon); }
void read_cb(struct bufferevent*bev, void*arg)//循环读取套接字里的内容; { #define MAX_LINE 256 char line[MAX_LINE+1]={0}; QR_HEAD *head; QA_HEAD qa_head; memset(&qa_head, 0, sizeof(QA_HEAD)); qa_head.package_len = 232; qa_head.package_id = 11; HashNode **getinfo;//储存查询结果信息; int n; int i=0; char *buf = malloc(sizeof(QA_HEAD)+4096); evutil_socket_t fd = bufferevent_getfd(bev);//获取套接字描述符; while(n = bufferevent_read(bev, line, MAX_LINE), n>0)//读取套接字中的内容; { head = (QR_HEAD*)line; printf("len %d\n", head->package_len); printf("id %d\n", head->package_id); printf("fd = %u, readline:%s", fd, (char*)(line+sizeof(QR_HEAD))); if(head->package_id == 9)//检测是不是reload包,通知重载hash表; { update_hash_table();//重载hash表内容; continue; } getinfo = hash_table_lookup(line+sizeof(QA_HEAD));//查询hash表; if(getinfo == NULL)//如果没有查询到响应的信息,设置包长度为包头长度; { qa_head.package_len = 8; memcpy(buf, &qa_head, sizeof(QA_HEAD)); } else { i = 0; while(getinfo[i])//循环往包里添加查询到的数据; { memcpy(buf+sizeof(QA_HEAD)+i*sizeof(INFOR), getinfo[i]->infor, sizeof(INFOR)); i++; } qa_head.package_len = sizeof(QA_HEAD)+i*sizeof(INFOR); memcpy(buf, &qa_head, sizeof(QA_HEAD)); } bufferevent_write(bev, buf, sizeof(QA_HEAD)+4096);//发包; } }
void CBareConnection::conn_event(bufferevent* bev, short event, void* ctx) { assert(bev != nullptr); assert(ctx != nullptr); CBareConnection* data = static_cast<CBareConnection*>(ctx); if ((event & BEV_EVENT_CONNECTED) != 0) data->OnConnectSuccess(std::move(data->m_bev)); else { evutil_socket_t sock = bufferevent_getfd(bev); (void)sock; // sock may be BAD_SOCKET here if it wasn't successfully created. int error = evutil_socket_geterror(sock); data->m_bev.free(); data->OnConnectFailure(event, error); } }
void buf_write_callback(struct bufferevent *incoming, void *arg) { conn *c; c = (conn*) arg; assert(c != NULL); int fd; fd = (int)bufferevent_getfd(incoming); if (fd != c->sfd){ perror("fd != sfd"); conn_close(c); return; } drive_machine(c, incoming); return; }
void QueryListener::onEvent(bufferevent *bufEvent, short events, void *arg) { QueryListener *_this = static_cast<QueryListener *>(arg); evutil_socket_t fd = bufferevent_getfd(bufEvent); // If socket is closed - delete it from the collection if (events & BEV_EVENT_EOF) { LogD(TAG, "event: BEV_EVENT_EOF fd=" + std::to_string(fd)); _this->connections.erase(bufEvent); } if (events & BEV_EVENT_ERROR) { LogD(TAG, "event: BEV_EVENT_ERROR fd=" + std::to_string(fd)); } }
const string TcpTransport::getPeerAddrAndPort() { struct sockaddr_in broker; socklen_t cLen = sizeof(broker); // getsockname(m_socket->getRawSocketHandle(), (struct sockaddr*) &s, &sLen); // // ! use connectSock here. getpeername(bufferevent_getfd(m_bufferEvent), (struct sockaddr *)&broker, &cLen); // ! use connectSock here. LOG_DEBUG("broker addr: %s, broker port: %d", inet_ntoa(broker.sin_addr), ntohs(broker.sin_port)); string brokerAddr(inet_ntoa(broker.sin_addr)); brokerAddr.append(":"); string brokerPort(UtilAll::to_string(ntohs(broker.sin_port))); brokerAddr.append(brokerPort); LOG_DEBUG("brokerAddr:%s", brokerAddr.c_str()); return brokerAddr; }
/* eventcb for bufferevent. For the purpose of simplicity and readability of the example program, we omitted the certificate and peer verification. After SSL/TLS handshake is over, initialize nghttp2 library session, and send client connection header. Then send HTTP request. */ static void eventcb(struct bufferevent *bev, short events, void *ptr) { http2_session_data *session_data = (http2_session_data *)ptr; if (events & BEV_EVENT_CONNECTED) { int fd = bufferevent_getfd(bev); int val = 1; const unsigned char *alpn = NULL; unsigned int alpnlen = 0; SSL *ssl; fprintf(stderr, "Connected\n"); ssl = bufferevent_openssl_get_ssl(session_data->bev); #ifndef OPENSSL_NO_NEXTPROTONEG SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen); #endif /* !OPENSSL_NO_NEXTPROTONEG */ #if OPENSSL_VERSION_NUMBER >= 0x10002000L if (alpn == NULL) { SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); } #endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) { fprintf(stderr, "h2 is not negotiated\n"); delete_http2_session_data(session_data); return; } setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); initialize_nghttp2_session(session_data); send_client_connection_header(session_data); submit_request(session_data); if (session_send(session_data) != 0) { delete_http2_session_data(session_data); } return; } if (events & BEV_EVENT_EOF) { warnx("Disconnected from the remote host"); } else if (events & BEV_EVENT_ERROR) { warnx("Network error"); } else if (events & BEV_EVENT_TIMEOUT) { warnx("Timeout"); } delete_http2_session_data(session_data); }
void cache_init_packet_from_server() { socklen_t len; struct bufferevent *bev; struct bev_arg *bev_arg; struct destination *destination=first_destination; struct sockaddr *s; bev = bufferevent_socket_new(event_base, -1, BEV_OPT_CLOSE_ON_FREE); bev_arg=malloc(sizeof (struct bev_arg)); bev_arg->type=BEV_CACHE; bev_arg->bev=bev; bev_arg->remote=NULL; /* set callback functions and argument */ bufferevent_setcb(bev, cache_mysql_init_packet_read_callback, NULL, cache_mysql_init_packet_event_callback, (void *)bev_arg); /* read buffer 64kb */ bufferevent_setwatermark(bev, EV_READ, 0, INPUT_BUFFER_LIMIT); if (destination->s[0] == SOCKET_TCP) { s = (struct sockaddr *) &destination->sin; len = destination->addrlen; } else { s = (struct sockaddr *) &destination->sun; len = destination->addrlen; } /* event_callback() will be called after nonblock connect() return */ if (bufferevent_socket_connect(bev, s, len)==-1) { bufferevent_free(bev); free(bev_arg); } struct linger l; l.l_onoff=1; l.l_linger=0; setsockopt(bufferevent_getfd(bev), SOL_SOCKET, SO_LINGER, (void *) &l, sizeof (l)); bufferevent_enable(bev, EV_READ); }
void read_cb(struct bufferevent *bev, void *arg) { #define MAX_LINE 2560 char line[MAX_LINE + 1]; char output[1000]; int n; evutil_socket_t fd = bufferevent_getfd(bev); while (n = bufferevent_read(bev, line, MAX_LINE), n > 0) { line[n] = '\0'; printf("fd=%u, read line: %s\n", fd, line); worker((int) fd, line, output); printf("out line: %s,len=%d\n", output,strlen(output)); bufferevent_write(bev, output, strlen(output)); } //close(fd); }
// 改成用bufferevent之后,接受的参数得改。。。 void event_handler(struct bufferevent *incoming, void *arg) { conn *c; c = (conn *)arg; assert(c != NULL); // c->which = which; int fd; fd = (int)bufferevent_getfd(incoming); if (fd != c->sfd) { perror("fd != sfd"); conn_close(c); return; } drive_machine(c, incoming); return; }
void MessageManager::ErrorDispatcher(struct bufferevent *bev, short error, void *ctx) { if(error & BEV_EVENT_CONNECTED) { LOG(DEBUG, "New connection established", ""); return; } if(error & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) { //If we're a server... if(ctx != NULL) { bufferevent_free(bev); MessageManager::Instance().DeleteEndpoint(bufferevent_getfd(bev)); } return; } }
zend_string * ion_stream_get_name_remote(ion_stream * stream) { int type = 0; evutil_socket_t socket; if(stream->name_remote == NULL) { if(!stream->buffer) { return NULL; } socket = bufferevent_getfd(stream->buffer); if(socket == -1) { return NULL; } else { type = pion_net_sock_name(socket, PION_NET_NAME_REMOTE, &stream->name_remote); if(type == PION_NET_NAME_UNKNOWN || type == FAILURE) { return NULL; } } } return zend_string_copy(stream->name_remote); }
static void ssh_handshake_cb(obfsproxyssh_client_session_t *session) { int rval; evutil_socket_t fd = bufferevent_getfd(session->ssh_ev); rval = libssh2_session_handshake(session->ssh_session, fd); if (LIBSSH2_ERROR_EAGAIN == rval) return; else if (0 != rval || 0 != ssh_validate_hostkey(session)) { libssh2_session_free(session->ssh_session); session->ssh_session = NULL; session_free(session); return; } session->libssh2_cb = ssh_auth_cb; session->libssh2_cb(session); }
void TcpTransport::eventcb(struct bufferevent *bev, short what, void *ctx) { evutil_socket_t fd = bufferevent_getfd(bev); TcpTransport *tcpTrans = (TcpTransport *)ctx; LOG_INFO("eventcb: received event:%x on fd:%d", what, fd); if (what & BEV_EVENT_CONNECTED) { int val = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); LOG_INFO("eventcb:connect to fd:%d successfully", fd); tcpTrans->setTcpConnectEvent(e_connectSuccess); } else if (what & (BEV_EVENT_ERROR | BEV_EVENT_EOF | BEV_EVENT_READING | BEV_EVENT_WRITING)) { LOG_INFO("eventcb:rcv error event cb:%x on fd:%d", what, fd); tcpTrans->setTcpConnectEvent(e_connectFail); bufferevent_setcb(bev, NULL, NULL, NULL, NULL); // bufferevent_disable(bev, EV_READ|EV_WRITE); // bufferevent_free(bev); } else { LOG_ERROR("eventcb: received error event:%d on fd:%d", what, fd); } }
static void connecting_event_cb(struct bufferevent *bev, short what, void *arg) { CONNECTOR *cr = (CONNECTOR *)arg; if (!(what & BEV_EVENT_CONNECTED)) { PUTS("connecting failed!, %d", time(NULL) ); if (0 == cr->keep_connect) { CONNECTOR_CALLBACK *cb = cr->cb; if ( cb->onConnect) (*(cb->onConnect))(cr, 0); } else { //delay_connecting(c); reconnect(cr, 5); } } else { CONNECTOR_CALLBACK *cb = cr->cb; int fd = bufferevent_getfd(bev); struct linger l; PUTS("connect %s success!%d", cr->addrtext, time(NULL)); cr->state = STATE_CONNECTED; if (cb->onConnect) (*(cb->onConnect))(cr, 1); /* prevent CLOSE_WAIT */ l.l_onoff = 1; l.l_linger = 0; setsockopt(fd, SOL_SOCKET, SO_LINGER, (const char *)&l, sizeof(l)); bufferevent_setcb(bev, read_client_cb, conn_write_cb, conn_event_cb2, cr); bufferevent_enable(bev, EV_READ); } }
void read_cb(struct bufferevent *bev, void *arg) { #define MAX_LINE 256 char line[MAX_LINE+1]; int n; evutil_socket_t fd = bufferevent_getfd(bev); net_para_t net; while (n = bufferevent_read(bev, line, MAX_LINE), n > 0) { line[n] = '\0'; printf("fd=%u, read line: %s\n", fd, line); net.net = bev; net.print = net_print; parse_and_exec_cmd(line, ifs_cmd_list, &net); line[0] = '>'; line[1] = 0; bufferevent_write(bev, line, 2); } }
//解析从Server发出的数据 bool TcpClient::DealWithData(struct bufferevent *bev, const char*pData, int nLen) { evutil_socket_t fd = bufferevent_getfd(bev); struct sockaddr_in sin; int nsocketLen = sizeof(SOCKADDR); char cIPParse[16]; ushort port; if (getpeername(fd, (struct sockaddr*)&sin, &nsocketLen) == 0) { inet_ntop(AF_INET, (void *)&sin.sin_addr, cIPParse, 16); port = ntohs(sin.sin_port); } m_pPacket->AppendRecvData(nLen, (byte*)pData); SolarPacket* pPacketData = m_pPacket->PullRecvPacket(); if (pPacketData != NULL) { switch (pPacketData->byteCmd) { case 0x10: break; case 0x11: break; case 0x12: break; case 0x13: break; case 0x14: break; case 0x15: break; } SolarTcpIpPacket::DestroySolarPacket(pPacketData); } return false; }
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; }
// error event socket ( all client socket) // connecting socket (client side client) static void sock_buffer_error_event(bufferevent *bev, short what, void *arg) { coro_sock *sock = (coro_sock *)arg; coro_event ev; ev.sock = bufferevent_getfd(bev); ev.sock = sock->sock; if ( what & BEV_EVENT_ERROR ) { SET_ERROR(sock->status); ev.event = SOCK_ERROR_NOTIFY; } else if ( what & BEV_EVENT_EOF ) { ev.event = SOCK_EOF_NOTIFY; SET_EOF(sock->status); if ( evbuffer_get_length(bufferevent_get_input(sock->bev)) ) { SET_READ(sock->status); // printf("set read: %d\n", ev.sock); } } else { ; // pass } sock->ctx->curev.push(ev); coro_yield_uthread(__g_coroutine_ctx->io, 0); }
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); if (fd < 0) { if (!sa) goto done; fd = evutil_socket_(sa->sa_family, SOCK_STREAM|EVUTIL_SOCK_NONBLOCK, 0); if (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; }
/* * accept socket, then create buffer events for self and remote */ void accept_connect(int sock, short event, void *arg) { struct listener *listener=(struct listener *)arg; socklen_t len; struct sockaddr_in sin; struct sockaddr_un sun; int csock=0; struct bufferevent *bev_client, *bev_target; struct bev_arg *bev_arg_client, *bev_arg_target; struct destination *destination=first_destination; struct sockaddr *s=NULL; if (listener->s[0]==SOCKET_TCP) { len = sizeof(struct sockaddr_in); s = (struct sockaddr *) &sin; } else if (listener->s[0]==SOCKET_UNIX) { len = sizeof(struct sockaddr_un); s = (struct sockaddr *) &sun; } csock=accept(sock, s, &len); if (csock==-1) { return; } fcntl(csock, F_SETFL, O_RDWR|O_NONBLOCK); listener->nr_allconn++; /* the first turn the switch on */ /* the last turn the switch off*/ listener->nr_conn++; bev_client = bufferevent_socket_new(event_base, csock, BEV_OPT_CLOSE_ON_FREE); bev_target = bufferevent_socket_new(event_base, -1, BEV_OPT_CLOSE_ON_FREE); /* CLIENT bev_arg*/ /* parameter for callback functions */ bev_arg_client=malloc(sizeof (struct bev_arg)); bev_arg_client->type=BEV_CLIENT; bev_arg_client->listener=listener; bev_arg_client->bev=bev_client; bev_arg_client->connecting=0; /* set callback functions and argument */ if (listener->type==LISTENER_DEFAULT) { if (!mysql_cdb_file) { bufferevent_setcb(bev_client, read_callback, NULL, event_callback, (void *)bev_arg_client); } else { /* if mysql_cdb is enabled, use different callback functions */ bev_arg_client->ms=init_ms(); bufferevent_setcb(bev_client, mysql_read_callback, NULL, mysql_event_callback, (void *)bev_arg_client); } } else if (listener->type==LISTENER_STATS) { bufferevent_setcb(bev_client, NULL, stats_write_callback, stats_event_callback, (void *)bev_arg_client); send_stats_to_client(bev_client); return; } /* read buffer 64kb */ bufferevent_setwatermark(bev_client, EV_READ, 0, INPUT_BUFFER_LIMIT); /* TARGET bev_arg*/ /* parameter for callback functions */ bev_arg_target=malloc(sizeof (struct bev_arg)); bev_arg_target->type=BEV_TARGET; bev_arg_target->connecting=0; bev_arg_client->remote=bev_arg_target; /* set callback functions and argument */ bev_arg_target->listener=listener; bev_arg_target->bev=bev_target; bev_arg_target->remote=bev_arg_client; if (!mysql_cdb_file) { bufferevent_setcb(bev_target, read_callback, NULL, event_callback, (void *)bev_arg_target); } else { /* mysql_stuff structure is same for client and target bufferevent */ bev_arg_target->ms=bev_arg_client->ms; bufferevent_setcb(bev_target, mysql_read_callback, NULL, mysql_event_callback, (void *)bev_arg_target); } /* read buffer 64kb */ bufferevent_setwatermark(bev_target, EV_READ, 0, INPUT_BUFFER_LIMIT); if (destination->s[0] == SOCKET_TCP) { s = (struct sockaddr *) &destination->sin; len = destination->addrlen; } else { s = (struct sockaddr *) &destination->sun; len = destination->addrlen; } /* we can use cached init packet only if we can use MITM attack, * we can use MITM attack only if we use mysql_cdb_file where are hashed user passwords */ if (!mysql_cdb_file || (mysql_cdb_file && !cache_mysql_init_packet)) { bev_arg_target->connecting=1; if (bufferevent_socket_connect(bev_target, s, len)==-1) { listener->nr_conn--; bufferevent_free(bev_client); bufferevent_free(bev_target); free(bev_arg_client); free(bev_arg_target); } bev_arg_target->connecting=0; struct linger l; l.l_onoff=1; l.l_linger=0; setsockopt(bufferevent_getfd(bev_target), SOL_SOCKET, SO_LINGER, (void *) &l, sizeof (l)); } else { /* use cached init packet */ bev_arg_client->remote=NULL; bev_arg_client->ms->not_need_remote=1; bev_arg_client->ms->handshake=1; /* we use bev_arg_client and ms pointers as random data for generating random string filled in init packet send to client */ /* TODO: use better random input */ bev_arg_client->ms->scramble1=set_random_scramble_on_init_packet(cache_mysql_init_packet, bev_arg_target, bev_arg_client->ms); bufferevent_free(bev_target); free(bev_arg_target); if (bufferevent_write(bev_client, cache_mysql_init_packet, cache_mysql_init_packet_len)==-1) { listener->nr_conn--; bufferevent_free(bev_client); bufferevent_free(bev_target); free(bev_arg_client); free(bev_arg_target); } bufferevent_enable(bev_client, EV_READ); } }
static void on_read(struct bufferevent *bev, void *ctx) { struct evbuffer *input; int fd; size_t len; char *line; char *emsg; char **argv = malloc(sizeof(char *)); int argc = 0; char *arg_ptr, *save_ptr; /* * 1: Unknown command * 2: Too few arguments * 3: Internal error * 4: Missing command */ int status; int i; input = bufferevent_get_input(bev); fd = bufferevent_getfd(bev); len = evbuffer_get_length(input); line = malloc(len + 1); evbuffer_copyout(input, line, len); if (len == 0) { status = 4; goto END; } if (line[len - 1] == '\n') { line[len - 1] = 0; } else { line[len] = 0; } arg_ptr = strtok_r(line, " ", &save_ptr); while (arg_ptr != NULL) { len = strlen(arg_ptr) + 1; argv[argc] = malloc(len); strncpy(argv[argc], arg_ptr, len); argv = realloc(argv, argc + 1); arg_ptr = strtok_r(NULL, " ", &save_ptr); argc++; } printf("%s LookingGlass: Received command \"%s\" with %d arguments", date(), argv[0], argc - 1); for (i = 1; i < argc; i++) { printf(" %d:\"%s\"", i, argv[i]); } printf(".\n"); status = call_function(argv[0], fd, argc, argv); END: switch (status) { case 1: emsg = "Unknown command"; write(fd, emsg, strlen(emsg)); fprintf(stdout, "%s LookingGlass: Error: Disconnecting client. Reason: %s: %s.\n", date(), emsg, argv[0]); break; case 2: emsg = "Too few arguments"; write(fd, emsg, strlen(emsg)); fprintf(stdout, "%s LookingGlass: Disconnecting client. Error: %s.\n", date(), emsg); break; case 3: emsg = "Internal error"; write(fd, emsg, strlen(emsg)); fprintf(stdout, "%s LookingGlass: Disconnecting client. Error: %s.\n", date(), emsg); break; case 4: emsg = "Missing command"; write(fd, emsg, strlen(emsg)); fprintf(stdout, "%s LookingGlass: Disconnecting client. Error: %s.\n", date(), emsg); break; default: printf("%s LookingGlass: Disconnecting client.\n", date()); break; } bufferevent_free(bev); for (i = 0; i < argc; i++) { free(argv[i]); } free(argv); free(line); }
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; }
struct bufferevent* red_connect_relay_ssl(const char *ifname, struct sockaddr_in *addr, SSL * ssl, bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb errorcb, void *cbarg, const struct timeval *timeout_write) { struct bufferevent *retval = NULL; struct bufferevent *underlying = NULL; int relay_fd = -1; int error; underlying = red_prepare_relay(ifname, NULL, NULL, NULL, NULL); if (!underlying) goto fail; relay_fd = bufferevent_getfd(underlying); if (timeout_write) bufferevent_set_timeouts(underlying, NULL, timeout_write); error = connect(relay_fd, (struct sockaddr*)addr, sizeof(*addr)); if (error && errno != EINPROGRESS) { log_errno(LOG_NOTICE, "connect"); goto fail; } retval = bufferevent_openssl_filter_new(bufferevent_get_base(underlying), underlying, ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS); if (!retval) { log_errno(LOG_NOTICE, "bufferevent_openssl_filter_new"); goto fail; } if (timeout_write) bufferevent_set_timeouts(retval, NULL, timeout_write); 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; } } return retval; fail: if (retval) { bufferevent_disable(retval, EV_READ|EV_WRITE); bufferevent_free(retval); } if (underlying) { bufferevent_disable(underlying, EV_READ|EV_WRITE); bufferevent_free(underlying); } if (relay_fd != -1) redsocks_close(relay_fd); return NULL; }
void ConnectionWrapper::init(bufferevent *bufEvent) { assert(bufEvent != nullptr); this->bufEvent = bufEvent; this->fd = bufferevent_getfd(bufEvent); LogD(TAG, "Connection established fd=" + std::to_string(fd)); }
bool ConnectToNovad() { if(IsNovadUp(false)) { return true; } DisconnectFromNovad(); //Create new base if(libeventBase == NULL) { evthread_use_pthreads(); libeventBase = event_base_new(); pthread_mutex_init(&bufferevent_mutex, NULL); } //Builds the key path string key = Config::Inst()->GetPathHome(); key += "/config/keys"; key += NOVAD_LISTEN_FILENAME; //Builds the address struct sockaddr_un novadAddress; novadAddress.sun_family = AF_UNIX; memset(novadAddress.sun_path, '\0', sizeof(novadAddress.sun_path)); strncpy(novadAddress.sun_path, key.c_str(), sizeof(novadAddress.sun_path)); { Lock buffereventLock(&bufferevent_mutex); bufferevent = bufferevent_socket_new(libeventBase, -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_UNLOCK_CALLBACKS | BEV_OPT_DEFER_CALLBACKS ); if(bufferevent == NULL) { LOG(ERROR, "Unable to create a socket to Nova", ""); DisconnectFromNovad(); return false; } bufferevent_setcb(bufferevent, MessageManager::MessageDispatcher, NULL, MessageManager::ErrorDispatcher, NULL); if(bufferevent_enable(bufferevent, EV_READ) == -1) { LOG(ERROR, "Unable to enable socket events", ""); return false; } if(bufferevent_socket_connect(bufferevent, (struct sockaddr *)&novadAddress, sizeof(novadAddress)) == -1) { bufferevent = NULL; LOG(DEBUG, "Unable to connect to NOVAD: "+string(strerror(errno))+".", ""); return false; } IPCSocketFD = bufferevent_getfd(bufferevent); if(IPCSocketFD == -1) { LOG(DEBUG, "Unable to connect to Novad: "+string(strerror(errno))+".", ""); bufferevent_free(bufferevent); bufferevent = NULL; return false; } if(evutil_make_socket_nonblocking(IPCSocketFD) == -1) { LOG(DEBUG, "Unable to connect to Novad", "Could not set socket to non-blocking mode"); bufferevent_free(bufferevent); bufferevent = NULL; return false; } MessageManager::Instance().DeleteEndpoint(IPCSocketFD); MessageManager::Instance().StartSocket(IPCSocketFD, bufferevent); } pthread_create(&eventDispatchThread, NULL, EventDispatcherThread, NULL); //Test if the connection is up Ticket ticket = MessageManager::Instance().StartConversation(IPCSocketFD); RequestMessage connectRequest(REQUEST_PING); if(!MessageManager::Instance().WriteMessage(ticket, &connectRequest)) { return false; } Message *reply = MessageManager::Instance().ReadMessage(ticket); if(reply->m_messageType == ERROR_MESSAGE && ((ErrorMessage*)reply)->m_errorType == ERROR_TIMEOUT) { LOG(DEBUG, "Timeout error when waiting for message reply", ""); delete reply; return false; } if(reply->m_messageType != REQUEST_MESSAGE) { stringstream s; s << "Expected message type of REQUEST_MESSAGE but got " << reply->m_messageType; LOG(DEBUG, s.str(), ""); reply->DeleteContents(); delete reply; return false; } RequestMessage *connectionReply = (RequestMessage*)reply; if(connectionReply->m_contents.m_requesttype() != REQUEST_PONG) { stringstream s; s << "Expected control type of CONTROL_CONNECT_REPLY but got " <<connectionReply->m_contents.m_requesttype(); LOG(DEBUG, s.str(), ""); reply->DeleteContents(); delete reply; return false; } delete connectionReply; return true; }
static void echo_read_cb(struct bufferevent *bev, void *ctx) { printf("echo_read_cb ctx:%p\n", ctx); /* This callback is invoked when there is data to read on bev. */ struct evbuffer *input = bufferevent_get_input(bev); /* Copy all the data from the input buffer to the output buffer. */ // evbuffer_add_buffer(output, input); // 能读到数据的时候 去连接其他server 而且是以阻塞的方式 printf("echo_read_cb1 \n"); struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); //servaddr.sin_family = AF_INET; ////servaddr.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ //if (inet_aton("192.168.1.104", &servaddr.sin_addr) == 0) //{ // perror("inet_aton failure!"); // printf("address:%u\n", servaddr.sin_addr.s_addr); // exit(EXIT_FAILURE); //} //servaddr.sin_port = htons(5188); /* Port 9876*/ // TODO 错误判断 char buff[64]; evutil_snprintf(buff, sizeof(buff), "%s:%d", "192.168.1.104", 5188); int servadd_len = sizeof(servaddr); //int retx = evutil_parse_sockaddr_port("192.168.1.104:5188", (struct sockaddr*)&servaddr, &servadd_len); int retx = evutil_parse_sockaddr_port(buff, (struct sockaddr*)&servaddr, &servadd_len); printf("address:%s\n", buff); if (retx < 0) { printf("address:error\n"); } else { printf("address:%u\n", servaddr.sin_addr.s_addr); } int sockconn; errno = 0; if ((sockconn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { perror("socket failure"); exit(EXIT_FAILURE); } //evutil_make_socket_nonblocking(sockconn); struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; setsockopt(sockconn, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); setsockopt(sockconn, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); // bufferevent_socket_new 只是分配内存 没有系统调用 struct bufferevent *bev1 = bufferevent_socket_new(ctx, sockconn, BEV_OPT_CLOSE_ON_FREE); //bufferevent_settimeout(bev1, 10, 10); //bev1 = bufferevent_socket_new(ctx, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_enable(bev1, EV_READ|EV_WRITE); bufferevent_setcb(bev1, NULL, NULL, eventcb, "hello"); //SetSocketBlockingEnabled(sockconn, 1); // 这里默认是阻塞的,会一直阻塞 直到连接成功 或超时 // // if (bufferevent_socket_connect(bev1, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { /* Error starting connection */ // 连接不能马上建立的时候 应该添加到写事件中 fprintf(stderr, "Connect failed.\n"); perror("connect..........."); //#define ETIMEDOUT 110 /* Connection timed out */ // 无条件超时 非自定义超时 走这里// //bufferevent_free(bev1); // 此时错误码是 BEV_EVENT_ERROR 在那里销毁 BEV_EVENT_ERROR //return -1; // 110错误码走到这里 11, 115错误码 不会走到这里 } printf("bufferevent_socket_connect return errno:%d \n", errno); ////#define EAGAIN 11 /* Try again */ ////#define ECONNREFUSED 111 /* Connection refused */ ////#define EINPROGRESS 115 /* Operation now in progress */ // connect 被超时打断11, // //if (errno != EAGAIN ) if (errno == EINPROGRESS) // 自定义 超时中断 { perror("self timeout............."); bufferevent_free(bev1); return; } else if (errno != 0) { perror("00buffevent_connect"); printf("bufferevent_socket_connect error\n"); //如果 在过程中 超时会被 打断 EINPROGRESS 115 /* Operation now in progress */ // 除了自定义超时timeout不宜在这里销毁 在 回调函数中销毁 不然调用不到回调函数// //bufferevent_free(bev1); return ; } else { // 连接成功 perror("11buffevent_connect"); printf("bufferevent_socket_connect success\n"); } //if (connect(sockconn, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) //{ // perror("connnect error"); // exit(EXIT_FAILURE); //} //else //{ // printf("connect success\n"); //} //char recvbuf[1024] = {0}; //memset(recvbuf, 0, sizeof(recvbuf)); //sleep(5); //read(sockconn, recvbuf, sizeof(recvbuf)); //printf("----%s-----\n", recvbuf); // struct evbuffer *input1 = bufferevent_get_input(bev1); // printf("before read ---------\n"); // bufferevent_read_buffer(bev1, input1); // size_t len = evbuffer_get_length(input1); // unsigned char * recvbuf = evbuffer_pullup(input1, len); // printf("end read len:%ld---------\n", len); // printf("----%s-----\n", recvbuf); //struct evbuffer * buffer = evbuffer_new(); struct evbuffer *buffer = bufferevent_get_input(bev1); struct evbuffer *buffero = bufferevent_get_output(bev1); evutil_socket_t fd = bufferevent_getfd(bev1); time_t rawtime; time ( &rawtime ); printf("before read ---------%ld\n", rawtime); int ret = evbuffer_read(buffer, fd, 1024); // not work // bufferevent_read_buffer(bev1, buffer); size_t len = evbuffer_get_length(buffer); time ( &rawtime ); printf("end readlen ---------%ld\n", len); unsigned char * recvbuf = evbuffer_pullup(buffer, len); printf("end read ---------%ld\n", rawtime); printf("----%s-----\n", recvbuf); evbuffer_drain(buffer, len); // int evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd); time ( &rawtime ); printf("before write---------%ld\n", rawtime); sleep(10); time ( &rawtime ); printf("before write1---------%ld\n", rawtime); evbuffer_add(buffero, "hello,china", 12); ret = evbuffer_write(buffero, fd); // ret =write(fd, "hello,china", 12); if (ret < 0) { if (errno != 0) { perror("write "); } } time ( &rawtime ); printf("end write1 ---------%ld\n", rawtime); // 出现read 在connect 之前// //root@debian:~/programming/libevent/libevent2/libevent/sample/study-buffevent_block# ./echoserver_block // create listener success, base:0xfdbc40 // echo_read_cb ctx:0xfdbc40 // echo_read_cb1 // bufferevent_socket_connect return errno:11 // 11buffevent_connect: Resource temporarily unavailable // bufferevent_socket_connect success // ----hello,world----- // Connect okay,-------------------------- hello. // disConnect --------------------------. }
void TcpTransport::readNextMessageIntCallback(struct bufferevent *bev, void *ctx) { /* This callback is invoked when there is data to read on bev. */ // protocol: <length> <header length> <header data> <body data> // 1 2 3 4 // rocketmq protocol contains 4 parts as following: // 1¡¢big endian 4 bytes int, its length is sum of 2,3 and 4 // 2¡¢big endian 4 bytes int, its length is 3 // 3¡¢use json to serialization data // 4¡¢application could self-defination binary data struct evbuffer *input = bufferevent_get_input(bev); while (1) { struct evbuffer_iovec v[4]; int n = evbuffer_peek(input, 4, NULL, v, sizeof(v) / sizeof(v[0])); int idx = 0; char hdr[4]; char *p = hdr; unsigned int needed = 4; for (idx = 0; idx < n; idx++) { if (needed) { unsigned int tmp = needed < v[idx].iov_len ? needed : v[idx].iov_len; memcpy(p, v[idx].iov_base, tmp); p += tmp; needed -= tmp; } else { break; } } if (needed) { LOG_DEBUG(" too little data received with sum = %d ", 4 - needed); return; } uint32 totalLenOfOneMsg = *(uint32 *)hdr; // first 4 bytes, which indicates 1st part of protocol uint32 bytesInMessage = ntohl(totalLenOfOneMsg); LOG_DEBUG("fd:%d, totalLen:" SIZET_FMT ", bytesInMessage:%d", bufferevent_getfd(bev), v[0].iov_len, bytesInMessage); uint32 len = evbuffer_get_length(input); if (len >= bytesInMessage + 4) { LOG_DEBUG("had received all data with len:%d from fd:%d", len, bufferevent_getfd(bev)); } else { LOG_DEBUG( "didn't received whole bytesInMessage:%d, from fd:%d, totalLen:%d", bytesInMessage, bufferevent_getfd(bev), len); return; // consider large data which was not received completely by now } if (bytesInMessage > 0) { MemoryBlock messageData(bytesInMessage, true); uint32 bytesRead = 0; char *data = messageData.getData() + bytesRead; bufferevent_read(bev, data, 4); bytesRead = bufferevent_read(bev, data, bytesInMessage); TcpTransport *tcpTrans = (TcpTransport *)ctx; tcpTrans->messageReceived(messageData); } } }