void kismet_conn_eventcb(struct bufferevent *bev, short event, void* args) { DEBUG(255, "kismet_conn_eventcb(%p, 0x%02x, %p);", bev, event, args); if (!(event & BEV_EVENT_CONNECTED)) { struct event_base* base = bufferevent_get_base(bev); struct server* node = (struct server*) args; bufferevent_free(node->conn); node->conn = NULL; struct timeval tv = {node->timeout, 0}; struct reconnect_struct* reconnect_struct = malloc(sizeof(struct reconnect_struct)); reconnect_struct->server = node; reconnect_struct->base = base; struct inserter* inserter = node->inserters; while (inserter) { if (inserter->capabilities) { unsigned int next_token = 0; while (inserter->capabilities[next_token]) free(inserter->capabilities[next_token++]); free(inserter->capabilities); inserter->capabilities = NULL; } inserter = inserter->next; }; event_base_once(base, -1, EV_TIMEOUT, reconnectServer, reconnect_struct, &tv); } };
/* * Handle socket events. */ static void v4c_srv_event(struct bufferevent *bev, short what, void *ctx) { struct event_base *base = bufferevent_get_base(bev); unused(ctx); /* Handle only one client. */ assert(bev == client); if (what & BEV_EVENT_READING) { ERR("Error while reading."); } if (what & BEV_EVENT_WRITING) { ERR("Error while writing."); } if (what & BEV_EVENT_EOF) { ERR("EOF reached."); } if (what & BEV_EVENT_ERROR) { ERR("Unrecoverable error encountered."); } if (what & BEV_EVENT_TIMEOUT) { ERR("Specified timout reached."); } if (what & BEV_EVENT_CONNECTED) { ERR("Connect operation done."); } if (what & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) { bufferevent_free(bev); client = NULL; event_base_loopexit(base, NULL); } }
/* Called periodically to check up on how full the buckets are */ static void check_bucket_levels_cb(evutil_socket_t fd, short events, void *arg) { struct bufferevent *bev = arg; ev_ssize_t r = bufferevent_get_read_limit(bev); ev_ssize_t w = bufferevent_get_write_limit(bev); ev_ssize_t rm = bufferevent_get_max_to_read(bev); ev_ssize_t wm = bufferevent_get_max_to_write(bev); /* XXXX check that no value is above the cofigured burst * limit */ total_rbucket_level += r; total_wbucket_level += w; total_max_to_read += rm; total_max_to_write += wm; #define B(x) \ if ((x) > max_bucket_level) \ max_bucket_level = (x); \ if ((x) < min_bucket_level) \ min_bucket_level = (x) B(r); B(w); #undef B total_n_bev_checks++; if (total_n_bev_checks >= .8 * ((double)cfg_duration / cfg_tick_msec) * cfg_n_connections) { event_free(event_base_get_running_event(bufferevent_get_base(bev))); } }
void on_event(struct bufferevent *bev, short event, void *arg){ struct evbuffer *output = bufferevent_get_output(bev); struct event_base *base = bufferevent_get_base(bev); char buf[MAXLEN]; //printf("event begin:%d\n", event); /*if(event & BEV_EVENT_READING){ printf("Read?\n"); }*/ /*if(event & BEV_EVENT_WRITING){ printf("Write?\n"); }*/ if(event & BEV_EVENT_EOF){ //printf("EOF.\n"); printf("Logged out.\n"); pthread_cancel(tid); pthread_cancel(disptid); bufferevent_free(bev); event_base_loopexit(base, NULL); } if(event & BEV_EVENT_ERROR){ printf("Error!\n"); } if(event & BEV_EVENT_TIMEOUT){ printf("Timeout!\n"); } if(event & BEV_EVENT_CONNECTED){ printf("Connected.\n"); buf[0] = 0x80; buf[1] = user & 0xFF; *((package *)(&buf[2])) = pkg[user]; evbuffer_add(output, buf, sizeof(pkg[user]) + 2); } }
void bufferevent_cb(struct bufferevent *bev, short events, void *ptr) { P_PORTTRANS p_trans = (P_PORTTRANS)ptr; struct event_base *base = bufferevent_get_base(bev); //只有使用bufferevent_socket_connect进行的连接才会得到CONNECTED的事件 if (events & BEV_EVENT_CONNECTED) { st_d_print("GOT BEV_EVENT_CONNECTED event! "); } else if (events & BEV_EVENT_ERROR) { st_d_error("GOT BEV_EVENT_ERROR event[%d]! ", p_trans->l_port); sc_free_trans(p_trans); } else if (events & BEV_EVENT_EOF) { st_d_error("GOT BEV_EVENT_EOF event[%d]! ", p_trans->l_port); sc_free_trans(p_trans); } else if (events & BEV_EVENT_TIMEOUT) { st_d_error("GOT BEV_EVENT_TIMEOUT event[%d]! ", p_trans->l_port); sc_free_trans(p_trans); } return; }
void gated_error_cb(struct bufferevent *bev, short what, void *arg) { struct event_base *base = bufferevent_get_base(bev); fprintf(stdout, "gated error cb!!!\n"); int err = EVUTIL_SOCKET_ERROR(); fprintf(stderr, "Got an error %d (%s) on the gated_error_cb." "Shutting down.\n", err, evutil_socket_error_to_string(err)); event_base_loopexit(base, NULL); }
static void maxconns_handler(const int fd, const short which, void *arg) { struct timeval t = {.tv_sec = 0, .tv_usec = 10000}; if (fd == -42 || allow_new_conns == false) { /* reschedule in 10ms if we need to keep polling */ evtimer_set(&maxconnsevent, maxconns_handler, 0); event_base_set(main_base, &maxconnsevent); evtimer_add(&maxconnsevent, &t); } else { evtimer_del(&maxconnsevent); accept_new_conns(true); } } static bool update_event(conn *c, const int new_flags) { assert(c != NULL); if (c->ev_flags == new_flags) return true; pthread_t tid = pthread_self(); if (tid == dispatcher_thread.thread_id) { struct event_base *base = c->event.ev_base; if (event_del(&c->event) == -1) return false; event_set(&c->event, c->sfd, new_flags, master_event_handler, (void *)c); event_base_set(base, &c->event); c->ev_flags = new_flags; if (event_add(&c->event, 0) == -1) return false; return true; }else{ struct event_base *base = bufferevent_get_base(c->buf_ev); bufferevent_free(c->buf_ev); c->buf_ev = bufferevent_new(c->sfd, event_handler, buf_write_callback, buf_error_callback, (void * )c); bufferevent_base_set(base, c->buf_ev); c->ev_flags = new_flags; if (bufferevent_enable(c->buf_ev, new_flags) == -1) return false; return true; } //这个也得改成bufferevent的形式 /* event_set(&c->event, c->sfd, new_flags, event_handler, (void *)c); event_base_set(base, &c->event); event_add(&c->event, 0); c->buf_ev = bufferevent_new(c->sfd, event_handler, event_handler, NULL, (void * )c); bufferevent_base_set(base, c->buf_ev); bufferevent_enable(c->buf_ev, new_flags); c->ev_flags = new_flags; if (event_add(&c->event, 0) == -1) return false; return true; */ }
/* Registers a ProxyServer with a ProxyClient, creating if it exists. */ void cxmap_register(struct ProxyServer *serv) { struct ProxyClient *client; if (!serv->path) { struct event_base *base = bufferevent_get_base(serv->bev); client = pclient_new(base, serv->location, NULL); g_debug("Creating a new ProxyClient object for %s", serv->location); } else { client = g_hash_table_lookup(tbl, serv->location); if (!client) { /* create new ProxyClient */ struct event_base *base = bufferevent_get_base(serv->bev); client = pclient_new(base, serv->location, serv->path); g_hash_table_insert(tbl, client->location, client); g_debug("Creating a new ProxyClient object for %s", serv->location); } else { g_debug("Reusing an existing ProxyClient for %s", serv->location); } } pclient_register(client, serv); }
void thread_bufferevent_cb(struct bufferevent *bev, short events, void *ptr) { P_TRANS_ITEM p_trans = (P_TRANS_ITEM)ptr; struct event_base *base = bufferevent_get_base(bev); int loop_terminate_flag = 0; //只有使用bufferevent_socket_connect进行的连接才会得到CONNECTED的事件 if (events & BEV_EVENT_CONNECTED) { st_d_print("GOT BEV_EVENT_CONNECTED event! "); } else if (events & BEV_EVENT_ERROR) { st_d_error("GOT BEV_EVENT_ERROR event[%d]! ", p_trans->usr_lport); ss_free_trans(p_trans->p_activ_item, p_trans); } else if (events & BEV_EVENT_EOF) { st_d_print("GOT BEV_EVENT_EOF event[%d]! ", p_trans->usr_lport); // 实际传输端结束,那么只针对这个传输,把对端的连接断开, // 由于TCP连接,那么对端的be_usr_srv和be_daemon_srv也会收到BEV_EVENT_EOF消息 ss_free_trans(p_trans->p_activ_item, p_trans); } else if (events & BEV_EVENT_TIMEOUT) { st_d_print("GOT BEV_EVENT_TIMEOUT event[%d]! ", p_trans->usr_lport); ss_free_trans(p_trans->p_activ_item, p_trans); } if (loop_terminate_flag) { bufferevent_free(bev); event_base_loopexit(base, NULL); } return; }
/* Check that the server sends back the same byte that the client sent. If MAX_REQUESTS have been reached, exit. Otherwise, start another client. */ static void client_read_cb(struct bufferevent *bev, void *ctx) { unsigned char tmp; struct event_base *base = bufferevent_get_base(bev); bufferevent_read(bev, &tmp, 1); if (tmp != 'A') { puts("Incorrect data received!"); exit(2); } bufferevent_free(bev); num_requests++; if (num_requests == MAX_REQUESTS) { event_base_loopbreak(base); } else { start_client(base); } }
static void on_peer_event(struct bufferevent* bev, short ev, void *arg) { struct peer* p = (struct peer*)arg; if (ev & BEV_EVENT_CONNECTED) { paxos_log_info("Connected to %s:%d", inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port)); p->status = ev; } else if (ev & BEV_EVENT_ERROR || ev & BEV_EVENT_EOF) { struct event_base* base; int err = EVUTIL_SOCKET_ERROR(); paxos_log_error("%s (%s:%d)", evutil_socket_error_to_string(err), inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port)); base = bufferevent_get_base(p->bev); bufferevent_free(p->bev); p->bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(p->bev, on_read, NULL, on_peer_event, p); event_add(p->reconnect_ev, &reconnect_timeout); p->status = ev; } else { paxos_log_error("Event %d not handled", ev); } }
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; }
static void smtp_conn_readcb(struct bufferevent *bev, void* args) { struct evbuffer* buffer = bufferevent_get_input(bev); struct email* email = (struct email*) args; size_t len; char* line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF); while (line) { if (email->mode != DATA) { if (string_equals(line, "QUIT")) bufferevent_write(bev, _221_BYE, strlen(_221_BYE)); else if (string_equals(line, "RSET")) bufferevent_write(bev, _502_NOT_SUPPORTED, strlen(_502_NOT_SUPPORTED)); } switch (email->mode) { case HEADERS: if (len >= 4 && !email->ehlo) { /* Could be an EHLO or HELO */ if (string_startsWith(line, "EHLO") || string_startsWith(line, "HELO")) { email->ehlo = 1; bufferevent_write(bev, _250_OK, strlen(_250_OK)); } } else if (email->ehlo) { if (!forEachCharacter(line, isEmailCharacters)) { if (string_startsWith(line, "MAIL FROM:<")) { char* addr = stripOutEmailAddress(line); if (addr) { char* query = create_check_email_from_query(addr); if (query) databaseQuery(query, check_email_from_callback, email); else bufferevent_write(bev, _550_NOT_ALLOWED, strlen(_550_NOT_ALLOWED)); SAFEFREE(addr); } else bufferevent_write(bev, _550_NOT_ALLOWED, strlen(_550_NOT_ALLOWED)); } else if (string_startsWith(line, "RCPT TO:<")) { char* addr = stripOutEmailAddress(line); if (addr) { char* query = create_check_email_to_query(addr); if (query) databaseQuery(query, check_email_to_callback, email); else bufferevent_write(bev, _550_NOT_ALLOWED, strlen(_550_NOT_ALLOWED)); SAFEFREE(addr); } else bufferevent_write(bev, _550_NOT_ALLOWED, strlen(_550_NOT_ALLOWED)); } else if (string_equals(line, "DATA")) { if (email_has_recipients(email)) { bufferevent_write(bev, _354_GO_AHEAD, strlen(_354_GO_AHEAD)); email->mode = DATA_HEADERS; } else bufferevent_write(bev, _503_BAD_SEQUENCE, strlen(_503_BAD_SEQUENCE)); } else bufferevent_write(bev, _550_NOT_ALLOWED, strlen(_550_NOT_ALLOWED)); } else bufferevent_write(bev, _502_NOT_SUPPORTED, strlen(_502_NOT_SUPPORTED)); } break; case DATA_HEADERS: if (strlen(line) == 0) email->mode = DATA; else if (!string_contains(line, ':')) { email->mode = DATA; email_append_data(email, line); } else if (string_startsWith(line, "Subject: ")) email_set_subject(email, line); break; case DATA: if (strlen(line) > 0) { if (string_equals(line, ".")) { bufferevent_write(bev, _250_OK, strlen(_250_OK)); email->mode = DATA_DONE; email_for_each_recipient(email, bufferevent_get_base(bev), launch_push_queries); } else email_append_data(email, line); } break; default: break; } #ifdef DEV printf("I got the following line: %s\n", line); #endif SAFEFREE(line); line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF); } }
int process_line(struct client* client, char* line, size_t len) { DEBUG(255, "Raw line: %s", line); char buf[65]; double double_number; int number; struct timeval tv = { 0, 0 }; if (strcmp(line, "MODULES") == 0) send_loaded_modules_info(client); else if (sscanf(line, "ENABLE %64s", buf) == 1) { struct module* module = get_module(buf); if (module) { struct enabled_mod* em = malloc(sizeof(struct enabled_mod)); em->module = module; em->id = 0; em->next = NULL; if (!client->mods) { client->mods = em; if (em->module->array_length == 1) client_send_data(client, "LOADED: %s %s ID %d", module_type_to_string(em->module->type), buf, em->id); else client_send_data(client, "LOADED: %s %s ID %d WITH %d ITEMS", module_type_to_string(em->module->type), buf, em->id, em->module->array_length); } else { em->id++; struct enabled_mod* lm = client->mods; if (lm->module == em->module) { client_send_data(client, "ERROR: ALREADY LOADED %s WITH ID %d", em->module->name, em->id); free(em); } else { while (lm) { if (lm->module == em->module) { client_send_data(client, "ERROR: ALREADY LOADED %s WITH ID %d", em->module->name, em->id); free(em); return 0; } em->id = lm->id + 1; if (!lm->next) break; lm = lm->next; }; lm->next = em; if (em->module->array_length == 1) client_send_data(client, "LOADED: %s %s ID %d", module_type_to_string(em->module->type), buf, em->id); else client_send_data(client, "LOADED: %s %s ID %d WITH %d ITEMS", module_type_to_string(em->module->type), buf, em->id, em->module->array_length); } } } else client_send_data(client, "ERROR: UNABLE TO LOAD %s", buf); } else if (sscanf(line, "DISABLE %64s", buf) == 1) { struct module* module = get_module(buf); if (module) { struct enabled_mod* lm = client->mods; if (lm->module == module) { client->mods = lm->next; client_send_data(client, "DISABLED: %s WITH ID %d", buf, lm->id); free(lm); } else { while (lm->next) { if (lm->next->module == module) { struct enabled_mod* to_free = lm->next; lm->next = lm->next->next; client_send_data(client, "DISABLED: %s WITH ID %d", buf, to_free->id); free(to_free); break; } lm = lm->next; }; } } else client_send_data(client, "ERROR: MODULE %s DOESN'T EXIST", buf); } else if (sscanf(line, "PULL %64s", buf) == 1) { struct module* module = get_module(buf); if (module) { char databuf[BUFSIZ]; if (update_value(module, databuf, sizeof(databuf), client)) client_send_data(client, "%s: %s", module->name, databuf); }; } else if (sscanf(line, "ITEMNAMES %64s", buf) == 1) { struct module* module = get_module(buf); if (module) { char databuf[BUFSIZ]; if (get_module_item_names(module, databuf, sizeof(databuf))) client_send_data(client, "%s: %s", module->name, databuf); }; } else if (sscanf(line, "INTERVAL %lf", &double_number) == 1) { if (client->timer) event_free(client->timer); if (double_number < 0) { client->timer = NULL; return 0; } tv.tv_sec = (long) double_number; tv.tv_usec = (long) ((double_number - (double) tv.tv_sec) * 1000000.0) ; client->timer = event_new(bufferevent_get_base(client->bev), -1, EV_PERSIST, client_timer, client); event_add(client->timer, &tv); } else if (sscanf(line, "PRECISION %d", &number) == 1) { if (number >= 0 && number <= 255) client->precision = number; else client_send_data(client, "ERROR: Precision %d is out of the valid range (0-255)", number); } else if ((!client->websocket || !client->websocket->connected) && handle_handshake(client, line, len)) return 0; else { switch (++client->unknown_command) { case 1: client_send_data(client, "ERROR: This is not a valid command..."); return 0; case 2: client_send_data(client, "ERROR: I'm warning you, stop that."); return 0; case 3: client_eventcb(client->bev, BEV_ERROR, client); return 1; } } client->unknown_command = 0; return 0; };
void srv_bufferevent_cb(struct bufferevent *bev, short events, void *ptr) { struct event_base *base = bufferevent_get_base(bev); int loop_terminate_flag = 0; //只有使用bufferevent_socket_connect进行的连接才会得到CONNECTED的事件 if (events & BEV_EVENT_CONNECTED) { st_d_print("GOT BEV_EVENT_CONNECTED event! "); } else if (events & BEV_EVENT_ERROR) { st_d_error("GOT BEV_EVENT_ERROR event! "); loop_terminate_flag = 1; } else if (events & BEV_EVENT_EOF) { st_d_print("GOT BEV_EVENT_EOF event! "); // main_be连接断开,这时候:如果是DAEMON端主动断开,那么USR端也要断开 // 否则,就让DAEMON进行重置(重新连接服务器) // 任何情况下,所有的服务都必须断开 // BEV_OPT_CLOSE_ON_FREE already closed the socket if (cltopt.C_TYPE == C_USR) { st_d_print("DAEMON已经退出,本端挂起!"); exit(EXIT_SUCCESS); } else { sc_free_all_trans(); st_d_print("DAEMON端重连服务器!"); int srv_fd; srv_fd = socket(AF_INET, SOCK_STREAM, 0); if (sc_connect_srv(srv_fd) != RET_YES) { st_d_error("连接服务器失败!"); event_base_loopexit(base, NULL); } if (sc_daemon_init_srv(srv_fd) != RET_YES) { st_d_error("(DAEMON)服务端返回错误!"); event_base_loopexit(base, NULL); } sc_set_eventcb_srv(srv_fd, base); st_d_print("(DAEMON)重连OK!"); } } else if (events & BEV_EVENT_TIMEOUT) { st_d_print("GOT BEV_EVENT_TIMEOUT event! "); } if (loop_terminate_flag) { bufferevent_free(bev); event_base_loopexit(base, NULL); } return; }
/** * 客户端和远程服务器的交互 */ void srv_bufferread_cb(struct bufferevent *bev, void *ptr) { size_t n = 0; CTL_HEAD head; struct evbuffer *input = bufferevent_get_input(bev); struct evbuffer *output = bufferevent_get_output(bev); if ( evbuffer_remove(input, &head, CTL_HEAD_LEN) != CTL_HEAD_LEN) { st_d_print("读取数据包头%d错误!", CTL_HEAD_LEN); return; } if (!sd_id128_equal(head.mach_uuid, cltopt.session_uuid)) { SYS_ABORT("服务端返回UUID校验失败:%s-%s", SD_ID128_CONST_STR(head.mach_uuid), SD_ID128_CONST_STR(cltopt.session_uuid)); } if (head.cmd == HD_CMD_ERROR) { st_d_error("SERVER RETURNED ERROR!"); exit(EXIT_SUCCESS); } if (head.cmd == HD_CMD_CONN_ACT) { P_PORTTRANS p_trans = sc_find_trans(head.extra_param); if (!p_trans) { SYS_ABORT("本地未找到连接信息:%d", head.extra_param); } bufferevent_enable(p_trans->local_bev, EV_READ|EV_WRITE); bufferevent_enable(p_trans->srv_bev, EV_READ|EV_WRITE); st_d_print("开始传输数据:%d", head.extra_param); } if (head.cmd == HD_CMD_END_TRANS) { P_PORTTRANS p_trans = sc_find_trans(head.extra_param); if (p_trans) { st_d_print("EXTRA CLOSE TRANS: %d", head.extra_param); sc_free_trans(p_trans); } } if (head.cmd == HD_CMD_SS5_ACT) { // OK,返回给本地程序告知可以开始传输了 // 这个绑定地址目前还没利用,主要是需要FTP这类需要带外传输另外连接端口的 char ret_msg[10] = "\x05\x00\x00\x01\x00\x00\x00\x00\x10\x10"; P_PORTTRANS p_trans = sc_find_trans(head.extra_param); if (!p_trans) { SYS_ABORT("本地SS5未找到连接信息:%d", head.extra_param); } bufferevent_enable(p_trans->local_bev, EV_READ|EV_WRITE); bufferevent_enable(p_trans->srv_bev, EV_READ|EV_WRITE); bufferevent_write(p_trans->local_bev, ret_msg, sizeof(ret_msg)); st_d_print("SS5准备传输数据:%d", head.extra_param); return; } if (head.cmd == HD_CMD_CONN) { assert(cltopt.C_TYPE == C_DAEMON); if (cltopt.C_TYPE == C_DAEMON) { sc_find_daemon_portmap(head.daemonport, 1); P_PORTTRANS p_trans = sc_create_trans(head.extra_param); p_trans->is_enc = 0; if (!p_trans) { st_d_error("本地无空闲TRANS!"); return; } /*建立本地连接*/ int local_fd = socket(AF_INET, SOCK_STREAM, 0); int reuseaddr_on = 1; if (setsockopt(local_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on)) == -1) { st_d_error("Reuse socket opt faile!\n"); return; } struct sockaddr_in local_srv; local_srv.sin_family = AF_INET; local_srv.sin_addr.s_addr = inet_addr("127.0.0.1"); local_srv.sin_port = htons(head.daemonport); if (connect(local_fd, (struct sockaddr *)&local_srv, sizeof(local_srv))) { st_d_error("连接本地端口%d失败!", head.daemonport); return; } else { st_d_print("连接本地端口%d OK!", head.daemonport); } /*建立服务器连接*/ int srv_fd = socket(AF_INET, SOCK_STREAM, 0); if(sc_connect_srv(srv_fd) != RET_YES) { st_d_error("连接服务器失败!"); return; } struct event_base *base = bufferevent_get_base(bev); evutil_make_socket_nonblocking(local_fd); struct bufferevent *local_bev = bufferevent_socket_new(base, local_fd, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(local_bev, bufferread_cb, NULL, bufferevent_cb, p_trans); //bufferevent_enable(local_bev, EV_READ|EV_WRITE); evutil_make_socket_nonblocking(srv_fd); struct bufferevent *srv_bev = bufferevent_socket_new(base, srv_fd, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(srv_bev, bufferread_cb, NULL, bufferevent_cb, p_trans); //bufferevent_enable(srv_bev, EV_READ|EV_WRITE); p_trans->l_port = head.extra_param; p_trans->local_bev = local_bev; p_trans->srv_bev = srv_bev; /* 向服务器报告连接请求 */ // 必须要发送CONN包,触发这个连接转移到线程池处理 CTL_HEAD ret_head; memset(&ret_head, 0, CTL_HEAD_LEN); ret_head.cmd = HD_CMD_CONN; ret_head.extra_param = p_trans->l_port; ret_head.mach_uuid = cltopt.session_uuid; ret_head.direct = DAEMON_USR; bufferevent_write(srv_bev, &ret_head, CTL_HEAD_LEN); st_d_print("DAEMON端准备OK!"); } } }