/* Initiate for tcpcopy server */ void interception_init(uint16_t port) { delay_table_init(srv_settings.hash_size); router_init(srv_settings.hash_size << 1); select_server_set_callback(interception_process); msg_listen_sock = msg_server_init(srv_settings.binded_ip, port); log_info(LOG_NOTICE, "msg listen socket:%d", msg_listen_sock); select_server_add(msg_listen_sock); firewall_sock = nl_firewall_init(); log_info(LOG_NOTICE, "firewall socket:%d", firewall_sock); select_server_add(firewall_sock); }
int select_server_add_wrapper(cpy_event_loop_t *loop, cpy_event_t *efd, int events) { select_server_add(efd->fd); return CPY_EVENT_OK; }
static void interception_process(int fd) { int diff, new_fd, i, pass_through_flag = 0; time_t now; unsigned long packet_id; struct iphdr *ip_header; struct msg_client_s *c_msg; if(fd == msg_listen_sock){ new_fd = accept(msg_listen_sock, NULL, NULL); set_sock_no_delay(new_fd); if(new_fd != -1){ select_server_add(new_fd); } }else if(fd == firewall_sock){ packet_id = 0; ip_header = nl_firewall_recv(firewall_sock, &packet_id); if(ip_header != NULL){ /* Check if it is the valid user to pass through firewall */ for(i = 0; i < srv_settings.passed_ips.num; i++){ if(srv_settings.passed_ips.ips[i] == ip_header->daddr){ pass_through_flag = 1; break; } } if(pass_through_flag){ /* Pass through the firewall */ dispose_netlink_packet(NF_ACCEPT, packet_id); }else{ router_update(ip_header); now = time(0); diff = now - last_clean_time; if(diff > CHECK_INTERVAL){ route_delete_obsolete(now); delay_table_delete_obsolete(now); last_clean_time = now; } /* Drop the packet */ dispose_netlink_packet(NF_DROP, packet_id); } } }else{ c_msg = msg_server_recv(fd); if(c_msg){ if(c_msg->type == CLIENT_ADD){ tc_log_debug1(LOG_NOTICE, "add client router:%u", ntohs(c_msg->client_port)); router_add(c_msg->client_ip, c_msg->client_port, fd); }else if(c_msg->type == CLIENT_DEL){ tc_log_debug1(LOG_NOTICE, "del client router:%u", ntohs(c_msg->client_port)); router_del(c_msg->client_ip, c_msg->client_port); } }else{ close(fd); select_server_del(fd); log_info(LOG_NOTICE, "close sock:%d", fd); } } }
/* This is for copying multiple ports */ void address_add_msg_conn(uint16_t local_port, uint32_t dst_ip, uint16_t dst_port) { addr[local_port].ip = dst_ip; addr[local_port].port = dst_port; addr[local_port].sock = msg_client_init(dst_ip, dst_port); select_server_add(addr[local_port].sock); }