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); } } }
void interception_output_stat(tc_event_timer_t *evt) { tc_log_info(LOG_NOTICE, 0, "total resp packets:%llu, all:%llu", tot_copy_resp_packs, tot_resp_packs); #if (!TCPCOPY_SINGLE) router_stat(); delay_table_delete_obsolete(tc_time()); #endif evt->msec = tc_current_time_msec + OUTPUT_INTERVAL; }
void route_delete_obsolete(time_t cur_time) { int i, count = 0, timeout; hash_node *hn; link_list *l; p_link_node ln; tc_log_info(LOG_NOTICE, 0, "router size:%u", table->total); #if (INTERCEPT_THREAD) pthread_mutex_lock(&mutex); #endif for (i = 0; i < table->size; i++) { l = table->lists[i]; if (l->size > 0) { while (true) { ln = link_list_tail(l); if (NULL == ln) { break; } hn = (hash_node *)ln->data; timeout = table->timeout; if (0 == hn->visit_cnt) { /* * If we have not received the second handshake packet * for more than 3 seconds,then we clear out router info */ timeout = 3; } if ((hn->access_time + timeout) < cur_time) { link_list_pop_tail(l); free(hn); ln->data = NULL; free(ln); table->total--; count++; } else { break; } } } } tc_log_info(LOG_NOTICE, 0, "router delete obsolete:%d", count); delay_table_delete_obsolete(cur_time); #if (INTERCEPT_THREAD) pthread_mutex_unlock(&mutex); #endif }
/* * === FUNCTION ====================================================================== * Name: delay_table_add * Description: add msg to delay table * ===================================================================================== */ void delay_table_add(uint64_t key,struct receiver_msg_st *msg){ linklist *msg_list=NULL; struct receiver_msg_st *cmsg = NULL; lnodeptr pnode=NULL; delay_table_delete_obsolete(key); msg_list =(linklist *)hash_find(table,key); cmsg = copy_message(msg); pnode = lnode_malloc((void *)cmsg); if(NULL == msg_list){ lCount++; msg_list = linklist_create(); hash_add(table,key,msg_list); } mCount++; linklist_append(msg_list,pnode); return; }
/* * === FUNCTION ====================================================================== * Name: delay_table_send * Description: send delayed message according key * ===================================================================================== */ void delay_table_send(uint64_t key,int fd){ linklist *msg_list=NULL; struct receiver_msg_st *msg=NULL; lnodeptr first=NULL; delay_table_delete_obsolete(key); msg_list =(linklist *)hash_find(table,key); if(NULL == msg_list){ return; } while(! linklist_is_empty(msg_list)){ first = linklist_pop_first(msg_list); msg = (first->data); (void)msg_receiver_send(fd,msg); if(msg != NULL) { free(msg); } fCount++; lnode_free(first); } }