void tc_intercept_release_tunnel(int fd, tc_event_t *rev) { if (!srv_settings.tunnel[fd].fd_valid) { tc_log_info(LOG_WARN, 0, "already released, fd:%d", fd); return; } tc_log_info(LOG_NOTICE, 0, "release tunnel related resources, fd:%d", fd); tc_socket_close(fd); srv_settings.tunnel[fd].fd_valid = 0; #if (INTERCEPT_COMBINED) if (srv_settings.tunnel[fd].combined != NULL) { free(srv_settings.tunnel[fd].combined); srv_settings.tunnel[fd].combined = NULL; } else { tc_log_info(LOG_NOTICE, 0, "crazy here, combined is null, fd:%d", fd); } #endif if (rev == NULL) { if (srv_settings.tunnel[fd].ev == NULL) { tc_log_info(LOG_NOTICE, 0, "crazy here, ev is null, fd:%d", fd); } else { tc_event_del(srv_settings.tunnel[fd].ev->loop, srv_settings.tunnel[fd].ev, TC_EVENT_READ); tc_event_destroy(srv_settings.tunnel[fd].ev, 1); srv_settings.tunnel[fd].ev = NULL; } } else { tc_event_del(rev->loop, rev, TC_EVENT_READ); } }
static int tc_msg_event_process(tc_event_t *rev) { msg_client_t msg; if (tc_socket_recv(rev->fd, (char *) &msg, MSG_CLIENT_SIZE) == TC_ERROR) { tc_socket_close(rev->fd); tc_log_info(LOG_NOTICE, 0, "close sock:%d", rev->fd); tc_event_del(rev->loop, rev, TC_EVENT_READ); return TC_ERROR; } switch (msg.type) { case CLIENT_ADD: tc_log_debug1(LOG_DEBUG, 0, "add client router:%u", ntohs(msg.client_port)); router_add(msg.client_ip, msg.client_port, rev->fd); break; case CLIENT_DEL: tc_log_debug1(LOG_DEBUG, 0, "del client router:%u", ntohs(msg.client_port)); router_del(msg.client_ip, msg.client_port); break; } return TC_OK; }
static int connect_to_server(tc_event_loop_t *ev_lp) { int i, j, fd; uint32_t target_ip; conns_t *conns; uint16_t target_port; for (i = 0; i < clt_settings.real_servers.num; i++) { conns = &(clt_settings.real_servers.conns[i]); target_ip = conns[i].ip; target_port = conns[i].port; if (target_port == 0) { target_port = clt_settings.srv_port; } if (conns[i].active != 0) { continue; } for (j = 0; j < conns->num; j++) { fd = conns->fds[j]; if (fd > 0) { tc_log_info(LOG_NOTICE, 0, "it close socket:%d", fd); tc_socket_close(fd); tc_event_del(clt_settings.ev[fd]->loop, clt_settings.ev[fd], TC_EVENT_READ); tc_event_destroy(clt_settings.ev[fd], 0); conns->fds[j] = -1; } } clt_settings.real_servers.conns[i].num = 0; clt_settings.real_servers.conns[i].remained_num = 0; for (j = 0; j < clt_settings.par_conns; j++) { fd = tc_message_init(ev_lp, target_ip, target_port); if (fd == TC_INVALID_SOCK) { return TC_ERR; } if (!send_version(fd)) { return TC_ERR; } if (j == 0) { clt_settings.real_servers.active_num++; conns[i].active = 1; } clt_settings.real_servers.conns[i].fds[j] = fd; clt_settings.real_servers.conns[i].num++; clt_settings.real_servers.conns[i].remained_num++; } } return TC_OK; }
static int tc_process_server_msg(tc_event_t *rev) { #if (TCPCOPY_DR) int i; #endif msg_server_t msg; if (tc_socket_recv(rev->fd, (char *) &msg, MSG_SERVER_SIZE) == TC_ERROR) { tc_log_info(LOG_ERR, 0, "Recv socket(%d)error, server may be closed", rev->fd); #if (TCPCOPY_DR) for (i = 0; i < clt_settings.real_servers.num; i++) { if (clt_settings.real_servers.fds[i] == rev->fd) { if (clt_settings.real_servers.active[i]) { clt_settings.real_servers.active[i] = 0; clt_settings.real_servers.active_num--; } tc_socket_close(rev->fd); tc_log_info(LOG_NOTICE, 0, "close sock:%d", rev->fd); tc_event_del(rev->loop, rev, TC_EVENT_READ); break; } } if (clt_settings.real_servers.active_num == 0) { return TC_ERR_EXIT; } else { return TC_OK; } #else return TC_ERR_EXIT; #endif } process((char *) &msg, REMOTE); return TC_OK; }
static int tc_process_server_msg(tc_event_t *rev) { #if (TCPCOPY_DR) int i, j; connections_t *connections; #endif #if (!TCPCOPY_COMBINED) int len; msg_server_t msg; #else int num, k; unsigned char *p, aggr_resp[COMB_LENGTH + sizeof(uint16_t)]; #endif #if (!TCPCOPY_COMBINED) len = MSG_SERVER_SIZE; #endif #if (!TCPCOPY_COMBINED) if (tc_socket_recv(rev->fd, (char *) &msg, len) == TC_ERROR) #else if (tc_socket_cmb_recv(rev->fd, &num, (char *) aggr_resp) == TC_ERROR) #endif { tc_log_info(LOG_ERR, 0, "Recv socket(%d)error", rev->fd); tc_log_info(LOG_ERR, 0, "server may be closed or"); tc_log_info(LOG_ERR, 0, "backend TCP/IP kernel memeory is too low or"); tc_log_info(LOG_ERR, 0, "the version of intercept may not be equal to the version of tcpcopy"); #if (TCPCOPY_DR) for (i = 0; i < clt_settings.real_servers.num; i++) { connections = &(clt_settings.real_servers.connections[i]); for (j = 0; j < connections->num; j++) { if (connections->fds[j] == rev->fd) { tc_socket_close(rev->fd); tc_log_info(LOG_NOTICE, 0, "close sock:%d", rev->fd); tc_event_del(rev->loop, rev, TC_EVENT_READ); connections->num--; if (connections->num == 0 && clt_settings.real_servers.active[i]) { clt_settings.real_servers.active[i] = 0; clt_settings.real_servers.active_num--; } break; } } } if (clt_settings.real_servers.active_num == 0) { return TC_ERR_EXIT; } else { return TC_OK; } #else return TC_ERR_EXIT; #endif } #if (!TCPCOPY_COMBINED) process_out((unsigned char *) &msg); #else tc_log_debug1(LOG_DEBUG, 0, "resp packets:%d", num); p = aggr_resp + sizeof(uint16_t); for (k = 0; k < num; k++) { process_out(p); p = p + MSG_SERVER_SIZE; } #endif return TC_OK; }
static int connect_to_server(tc_event_loop_t *event_loop) { int i, j, fd; uint32_t target_ip; uint16_t target_port; connections_t *connections; /* * add connections to the real servers for sending router info * and receiving response packet */ for (i = 0; i < clt_settings.real_servers.num; i++) { target_ip = clt_settings.real_servers.ips[i]; target_port = clt_settings.real_servers.ports[i]; if (target_port == 0) { target_port = clt_settings.srv_port; } if (clt_settings.real_servers.active[i] != 0) { continue; } connections = &(clt_settings.real_servers.connections[i]); for (j = 0; j < connections->num; j++) { fd = connections->fds[j]; if (fd > 0) { tc_log_info(LOG_NOTICE, 0, "it close socket:%d", fd); tc_socket_close(fd); tc_event_del(clt_settings.ev[fd]->loop, clt_settings.ev[fd], TC_EVENT_READ); tc_event_destroy(clt_settings.ev[fd]); connections->fds[j] = -1; } } clt_settings.real_servers.connections[i].num = 0; clt_settings.real_servers.connections[i].remained_num = 0; for (j = 0; j < clt_settings.par_connections; j++) { fd = tc_message_init(event_loop, target_ip, target_port); if (fd == TC_INVALID_SOCKET) { return TC_ERROR; } if (!send_version(fd)) { return TC_ERROR; } if (j == 0) { clt_settings.real_servers.active_num++; clt_settings.real_servers.active[i] = 1; } clt_settings.real_servers.connections[i].fds[j] = fd; clt_settings.real_servers.connections[i].num++; clt_settings.real_servers.connections[i].remained_num++; } tc_log_info(LOG_NOTICE, 0, "add dr tunnels for exchanging info:%u:%u", target_ip, target_port); } return TC_OK; }