int address_find_sock(uint32_t ip, uint16_t port) { int fd; uint64_t key; connections_t *connections; ip_port_pair_mapping_t *test; test = get_test_pair(&(clt_settings.transfer), ip, port); if (test == NULL) { tc_log_info(LOG_WARN, 0, "it can't find test pair,%u:%u", ntohl(ip), ntohs(port)); return -1; } key = get_key(test->online_ip, test->online_port); connections = hash_find(addr_table, key); if (connections == NULL) { tc_log_info(LOG_WARN, 0, "it can't find address socket,%u:%u", ntohl(ip), ntohs(port)); return -1; } fd = connections->fds[connections->index]; connections->index = (connections->index + 1) % connections->num; return fd; }
/* * The main procedure for processing the filtered packets */ bool process(char *packet, int pack_src) { ssize_t send_len; uint16_t size_ip, tot_len; struct iphdr *ip_header; struct udphdr *udp_header; ip_port_pair_mapping_t *test; ip_header = (struct iphdr*)packet; size_ip = ip_header->ihl<<2; tot_len = ntohs(ip_header->tot_len); udp_header = (struct udphdr*)((char *)ip_header + size_ip); test = get_test_pair(&(clt_settings.transfer), ip_header->saddr, udp_header->source); ip_header->daddr = test->target_ip; udp_header->dest = test->target_port; udpcsum(ip_header, udp_header); ip_header->check = 0; ip_header->check = csum((unsigned short *)ip_header, size_ip); send_len = send_ip_packet(ip_header, tot_len); if (-1 == send_len) { log_info(LOG_ERR, "send to back error,tot_len:%d", tot_len); return false; } return true; }
/* * the main procedure for processing udp packets */ bool tc_proc_ingress(tc_iph_t *ip, tc_udpt_t *udp) { int ret; uint16_t tot_len; transfer_map_t *test; tot_len = ntohs(ip->tot_len); test = get_test_pair(&(clt_settings.transfer), ip->daddr, udp->dest); if (test == NULL) { tc_log_info(LOG_ERR, 0, "retrieve test pair error"); return false; } ip->daddr = test->target_ip; udp->dest = test->target_port; udpcsum(ip, udp); /* check if it needs fragmentation */ if (tot_len > clt_settings.mtu) { ip_fragmentation(ip); } else { ret = tc_raw_socket_snd(tc_raw_socket_out, ip, tot_len, ip->daddr); if (ret == TC_ERR) { tc_log_info(LOG_ERR, 0, "send to back error,tot_len:%d", tot_len); } clt_udp_send_cnt++; } return true; }
/* * the main procedure for processing the filtered packets */ bool process(char *packet, int pack_src) { int diff; time_t cur_time; ssize_t send_len; uint16_t size_ip, tot_len; struct iphdr *ip_header; struct udphdr *udp_header; ip_port_pair_mapping_t *test; /* TODO time update will be optimized later */ cur_time = time(0); if (last_record_time != 0) { diff = cur_time - last_record_time; if (diff > 3) { log_info(LOG_INFO, "udp packets captured:%llu,packets sent:%llu", clt_udp_cnt, clt_udp_send_cnt); last_record_time = cur_time; } } else { last_record_time = cur_time; } ip_header = (struct iphdr *)packet; size_ip = ip_header->ihl<<2; tot_len = ntohs(ip_header->tot_len); udp_header = (struct udphdr*)((char *)ip_header + size_ip); test = get_test_pair(&(clt_settings.transfer), ip_header->daddr, udp_header->dest); ip_header->daddr = test->target_ip; udp_header->dest = test->target_port; udpcsum(ip_header, udp_header); ip_header->check = 0; ip_header->check = csum((unsigned short *)ip_header, size_ip); /* check if it needs fragmentation */ if (tot_len > clt_settings.mtu) { ip_fragmentation(ip_header, udp_header); } else { send_len = send_ip_packet(ip_header, tot_len); if (-1 == send_len) { log_info(LOG_ERR, "send to back error,tot_len:%d", tot_len); return false; } clt_udp_send_cnt++; } return true; }
int address_find_sock(uint32_t ip, uint16_t port) { void *fd; uint64_t key; ip_port_pair_mapping_t *test; test = get_test_pair(&(clt_settings.transfer), ip, port); if (test == NULL) { tc_log_info(LOG_WARN, 0, "it can't find test pair,%u:%u", ntohl(ip), ntohs(port)); return -1; } key = get_key(test->online_ip, test->online_port); fd = hash_find(addr_table, key); if (fd == NULL) { tc_log_info(LOG_WARN, 0, "it can't find address socket,%u:%u", ntohl(ip), ntohs(port)); return -1; } return (int) (long) fd; }
static bool process_packet(tc_user_t *u, unsigned char *frame) { bool result; uint16_t size_ip, size_tcp, tot_len, cont_len; uint32_t h_ack, h_last_ack; tc_ip_header_t *ip_header; tc_tcp_header_t *tcp_header; ip_port_pair_mapping_t *test; ip_header = (tc_ip_header_t *) (frame + ETHERNET_HDR_LEN); size_ip = ip_header->ihl << 2; tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip); size_tcp = tcp_header->doff << 2; tot_len = ntohs(ip_header->tot_len); cont_len = tot_len - size_tcp - size_ip; if (u->dst_port == 0) { test = get_test_pair(&(clt_settings.transfer), ip_header->daddr, tcp_header->dest); if (test == NULL) { tc_log_info(LOG_NOTICE, 0, " test null:%u", ntohs(tcp_header->dest)); tc_log_trace(LOG_WARN, 0, TO_BAKEND_FLAG, ip_header, tcp_header); return false; } u->dst_addr = test->target_ip; u->dst_port = test->target_port; #if (GRYPHON_PCAP_SEND) u->src_mac = test->src_mac; u->dst_mac = test->dst_mac; #endif } if (u->state.last_ack_recorded) { if (u->state.status < SEND_REQ && (u->state.status & SYN_CONFIRM)) { h_ack = ntohl(tcp_header->ack_seq); h_last_ack = ntohl(u->history_last_ack_seq); if (after(h_ack, h_last_ack)) { tc_log_debug1(LOG_DEBUG, 0, "server resp first, wait, p:%u", ntohs(u->src_port)); u->state.resp_waiting = 1; return false; } } } ip_header->saddr = u->src_addr; tcp_header->source = u->src_port; u->history_last_ack_seq = tcp_header->ack_seq; u->state.last_ack_recorded = 1; tcp_header->ack_seq = u->exp_ack_seq; ip_header->daddr = u->dst_addr; tcp_header->dest = u->dst_port; tc_log_debug2(LOG_DEBUG, 0, "set ack seq:%u, p:%u", ntohl(u->exp_ack_seq), ntohs(u->src_port)); packs_sent_cnt++; if (tcp_header->syn) { syn_sent_cnt++; #if (!GRYPHON_SINGLE) if (!send_router_info(u, CLIENT_ADD)) { return false; } #endif u->state.last_ack_recorded = 0; u->state.status |= SYN_SENT; } else if (tcp_header->fin) { fin_sent_cnt++; u->state.status |= CLIENT_FIN; } else if (tcp_header->rst) { rst_sent_cnt++; u->state.status |= CLIENT_FIN; tc_log_debug1(LOG_DEBUG, 0, "a reset packet to back:%u", ntohs(u->src_port)); } if (cont_len > 0) { cont_sent_cnt++; u->state.status |= SEND_REQ; } if (u->state.timestamped) { update_timestamp(u, tcp_header); } tcp_header->check = 0; tcp_header->check = tcpcsum((unsigned char *) ip_header, (unsigned short *) tcp_header, (int) (tot_len - size_ip)); #if (GRYPHON_PCAP_SEND) ip_header->check = 0; ip_header->check = csum((unsigned short *) ip_header,size_ip); #endif tc_log_debug_trace(LOG_DEBUG, 0, TO_BAKEND_FLAG, ip_header, tcp_header); #if (!GRYPHON_PCAP_SEND) result = tc_raw_socket_send(tc_raw_socket_out, ip_header, tot_len, ip_header->daddr); #else fill_frame((struct ethernet_hdr *) frame, u->src_mac, u->dst_mac); result = tc_pcap_send(frame, tot_len + ETHERNET_HDR_LEN); #endif if (result == TC_OK) { u->last_sent_time = tc_time(); return true; } else { tc_log_info(LOG_ERR, 0, "send to back error,tot_len is:%d,cont_len:%d", tot_len,cont_len); #if (!TCPCOPY_PCAP_SEND) tc_raw_socket_out = TC_INVALID_SOCKET; #endif tc_over = SIGRTMAX; return false; } }