コード例 #1
0
ファイル: tc_capture.c プロジェクト: nettedfish/tcpcopy
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;
}
コード例 #2
0
static void 
remove_obsolete_resources(int is_full) 
{
    time_t      thresh_access_tme;
    uint32_t    i, cnt = 0;
    link_list  *l;
    hash_node  *hn;
    p_link_node ln, next_ln;

    if (ctx.table == NULL || ctx.table->total == 0) {
        return;
    }

    if (is_full) {
        thresh_access_tme = tc_time() + 1;
    } else {
        thresh_access_tme = tc_time() - MAX_IDLE_TIME;
    }

    for (i = 0; i < ctx.table->size; i ++) {
        l  = get_link_list(ctx.table, i);
        if (l->size > 0) {
            ln = link_list_first(l);
            while (ln) {
                hn = (hash_node *) ln->data;
                next_ln = link_list_get_next(l, ln);
                if (hn->access_time < thresh_access_tme) {
                    release_resources(hn->key);
                }
                ln = next_ln;
            }
            
            cnt += l->size;

            if (ctx.table->total == cnt) {
                break;
            }
        }
    }
}
コード例 #3
0
ファイル: tc_interception.c プロジェクト: hy0kl/tcpcopy
static void
tc_nl_check_cleaning()
{
    int      diff;
    time_t   now;

    now  = tc_time();
    diff = now - last_clean_time;
    if (diff > CHECK_INTERVAL) {
        route_delete_obsolete(now);
        last_clean_time = now;
    }
}
コード例 #4
0
ファイル: tc_user.c プロジェクト: chu888chu888/Linux-gryphon
static void 
check_replay_complete()
{
#if (!GRYPHON_COMET)
    int  diff;

    if (last_resp_time) {
        diff = tc_time() - last_resp_time;
        if (diff > DEFAULT_TIMEOUT) {
            tc_over = 1;
        }
    }
#endif
}
コード例 #5
0
static void
tc_nl_check_cleaning()
{
    int      diff;
    time_t   now;

    now  = tc_time();
    diff = now - last_clean_time;
    if (diff > CHECK_INTERVAL) {
        tc_log_info(LOG_NOTICE, 0, "total response packets:%llu",
                tot_resp_packs);
        route_delete_obsolete(now);
        last_clean_time = now;
    }
}
コード例 #6
0
ファイル: tc_user.c プロジェクト: chu888chu888/Linux-gryphon
static tc_user_t *
tc_retrieve_active_user()
{
    int        total, speed;
    time_t     cur;
    tc_user_t *u; 

    cur = tc_time();

    if (record_time == 0) {
        record_time = cur;
    }

    if (init_phase) {
        total = base_user_seq + relative_user_seq;
        if (total >= size_of_users) {
           tc_log_info(LOG_NOTICE, 0, "total is larger than size of users");
           init_phase = false;
           u = user_array + 0;
           base_user_seq = 1 % size_of_users;
        } else {
            u = user_array + total;
            speed = clt_settings.conn_init_sp_fact;
            relative_user_seq = (relative_user_seq + 1) % speed;

            if (relative_user_seq == 0) {
                if (record_time != cur) {
                    base_user_seq += speed;
                    record_time = cur;
                    tc_log_info(LOG_NOTICE, 0, "change record time");
                    total = total + 1;
                    if (total == size_of_users) {
                        init_phase = false;
                        tc_log_info(LOG_NOTICE, 0, "set init phase false");
                    }
                }
            }
        }
      
    } else {
        u = user_array + base_user_seq;
        base_user_seq = (base_user_seq + 1) % size_of_users;
    }

    return u;
}
コード例 #7
0
ファイル: tc_interception.c プロジェクト: togear/tcpcopy
static void
tc_check_cleaning()
{
    int      diff;
    time_t   now;

    now  = tc_time();
    diff = now - last_clean_time;
    if (diff > CHECK_INTERVAL) {
        tc_log_info(LOG_NOTICE, 0, "total resp packets:%llu, all:%llu",
                tot_copy_resp_packs, tot_resp_packs);
#if (!TCPCOPY_SINGLE)  
        route_delete_obsolete(now);
#endif
        last_clean_time = now;
    }
}
コード例 #8
0
ファイル: tc_packets_module.c プロジェクト: TerryTsui/tcpcopy
static void
tc_process_offline_packet(tc_event_timer_t *evt)
{
    int diff = 0;  

    if (!read_pcap_over) {
        send_packets_from_pcap(0);
    } else {
        diff = tc_time() - read_pcap_over_time;
        if (diff > DEFAULT_SESSION_TIMEOUT) {
            tc_over = SIGRTMAX;
            tc_log_info(LOG_NOTICE, 0, "offline replay is complete");
        }
    }

    evt->msec = tc_current_time_msec;
}
コード例 #9
0
ファイル: tc_interception.c プロジェクト: hanshenu/tcpcopy
void
interception_push(tc_event_timer_t *evt)
{
    send_buffered_packets(tc_time());
    evt->msec = tc_current_time_msec + CHECK_INTERVAL;
}
コード例 #10
0
ファイル: tc_user.c プロジェクト: chu888chu888/Linux-gryphon
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;
    }
}
コード例 #11
0
ファイル: tc_user.c プロジェクト: chu888chu888/Linux-gryphon
static bool send_stop(tc_user_t *u) 
{
    int       send_diff;
    long      app_resp_diff;
    uint32_t  srv_sk_buf_s;

    if (u->orig_frame == NULL) {
        tc_log_debug1(LOG_DEBUG, 0, "orig frame is null :%d", 
                ntohs(u->src_port));
        return true;
    }

    if (u->state.status & SYN_SENT) {
        if (!(u->state.status & SYN_CONFIRM)) {
            tc_log_debug1(LOG_DEBUG, 0, "client wait server handshake:%d", 
                    ntohs(u->src_port));
            return true;
        }
    }

    if (u->state.status & CLIENT_FIN) {
        if (!(u->state.status & SERVER_FIN)) {
            tc_log_debug1(LOG_DEBUG, 0, "client wait server fin:%d", 
                ntohs(u->src_port));
            return true;
        }
    }

    send_diff = tc_time() - u->last_sent_time;
    if (send_diff >= 3) {
        tc_log_debug1(LOG_DEBUG, 0, "timeout, need to send more packet:%d", 
                ntohs(u->src_port));
        u->state.resp_waiting = 0; 
        return false;
    }

    if (u->state.resp_waiting) {
            tc_log_debug1(LOG_DEBUG, 0, "client wait server resp:%d", 
                ntohs(u->src_port));
        return true;
    }

    if (u->state.status & SEND_REQ) {
        if (u->orig_frame->next != NULL) {
            srv_sk_buf_s = u->orig_frame->next->seq - u->orig_frame->seq;
            srv_sk_buf_s = srv_sk_buf_s + u->orig_frame->seq - u->last_ack_seq;
            if (srv_sk_buf_s > u->srv_window) {
                tc_log_debug3(LOG_DEBUG, 0, "wait,srv_sk_buf_s:%u,win:%u,p:%u",
                        srv_sk_buf_s, u->srv_window, ntohs(u->src_port));
                return true;
            }
        }

    }

    app_resp_diff = tc_milliscond_time() - u->last_recv_resp_cont_time;
    if (app_resp_diff <= 10) {
        tc_log_debug1(LOG_DEBUG, 0, "need to wait resp complete:%d", 
                ntohs(u->src_port));
        return true;
    }

    tc_log_debug1(LOG_DEBUG, 0, "last resort, set stop false:%d", 
                ntohs(u->src_port));

    return false;
}
コード例 #12
0
ファイル: tc_user.c プロジェクト: chu888chu888/Linux-gryphon
void process_outgress(unsigned char *packet)
{
    uint16_t           size_ip, size_tcp, tot_len, cont_len;
    uint32_t           seq, ack_seq;
    uint64_t           key;
    tc_user_t         *u;
    tc_ip_header_t    *ip_header;
    tc_tcp_header_t   *tcp_header;

    last_resp_time = tc_time();
    resp_cnt++;
    ip_header  = (tc_ip_header_t *) packet;
    size_ip    = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);


    key = tc_get_key(ip_header->daddr, tcp_header->dest);
    tc_log_debug1(LOG_DEBUG, 0, "key from bak:%llu", key);
    u = tc_retrieve_user(key);

    if (u != NULL) {

        tc_log_debug_trace(LOG_DEBUG, 0, BACKEND_FLAG, ip_header, tcp_header);
        u->srv_window = ntohs(tcp_header->window);
        if (u->wscale) {
            u->srv_window = u->srv_window << (u->wscale);
            tc_log_debug1(LOG_DEBUG, 0, "window size:%u", u->srv_window);
        }
        if (u->state.timestamped) {
            retrieve_options(u, REMOTE, tcp_header);
        }
        size_tcp = tcp_header->doff << 2;
        tot_len  = ntohs(ip_header->tot_len);
        cont_len = tot_len - size_tcp - size_ip;

        if (ip_header->daddr != u->src_addr || tcp_header->dest!= u->src_port) {
            tc_log_info(LOG_NOTICE, 0, " key conflict");
        }
        seq = ntohl(tcp_header->seq);
        u->exp_seq = tcp_header->ack_seq;
        ack_seq = ntohl(tcp_header->ack_seq);

        if (u->last_seq == seq && u->last_ack_seq == ack_seq) {
            u->fast_retransmit_cnt++;
            if (u->fast_retransmit_cnt == 3) {
                fast_retransmit(u, ack_seq);
                return;
            }
        } else {
            update_ack_packets(u, ack_seq);
            u->fast_retransmit_cnt = 0;
        }

        u->last_ack_seq =  ack_seq;
        u->last_seq =  seq;


        if (cont_len > 0) {
            u->last_recv_resp_cont_time = tc_milliscond_time();
            resp_cont_cnt++;
            u->state.resp_waiting = 0;   
            u->exp_ack_seq = htonl(seq + cont_len);
            send_faked_ack(u);
        } else {
            u->exp_ack_seq = tcp_header->seq;
        }
        
        if (tcp_header->syn) {
            tc_log_debug1(LOG_DEBUG, 0, "recv syn from back:%u", 
                    ntohs(u->src_port));
            u->exp_ack_seq = htonl(ntohl(u->exp_ack_seq) + 1);
            if (!u->state.resp_syn_received) {
                conn_cnt++;
                active_conn_cnt++;
                u->state.resp_syn_received = 1;
                u->state.status |= SYN_CONFIRM;
                tc_log_debug2(LOG_DEBUG, 0, "exp ack seq:%u, p:%u",
                        ntohl(u->exp_ack_seq), ntohs(u->src_port));
                if (size_tcp > TCP_HEADER_MIN_LEN) {
                    retrieve_options(u, REMOTE, tcp_header);
                    if (u->wscale > 0) {
                        tc_log_debug2(LOG_DEBUG, 0, "wscale:%u, p:%u",
                                u->wscale, ntohs(u->src_port));
                    }
                }
                process_user_packet(u);

            } else {
                tc_log_debug1(LOG_DEBUG, 0, "syn, but already syn received:%u",
                    ntohs(u->src_port));
            }
        } else if (tcp_header->fin) {
            tc_log_debug1(LOG_DEBUG, 0, "recv fin from back:%u", 
                    ntohs(u->src_port));
            u->exp_ack_seq = htonl(ntohl(u->exp_ack_seq) + 1);
            u->state.status  |= SERVER_FIN;
            send_faked_ack(u);
            process_user_packet(u);
            fin_recv_cnt++;

        } else if (tcp_header->rst) {
            tc_log_info(LOG_NOTICE, 0, "recv rst from back:%u", 
                    ntohs(u->src_port));
            rst_recv_cnt++;
            if (u->state.status == SYN_SENT) {
                if (!u->state.over) {
                    conn_reject_cnt++;
                }
            }

            u->state.over = 1;
            u->state.status  |= SERVER_FIN;
        }

    } else {
        tc_log_debug_trace(LOG_DEBUG, 0, BACKEND_FLAG, ip_header,
                tcp_header);
        tc_log_debug0(LOG_DEBUG, 0, "no active session for me");
    }

}
コード例 #13
0
ファイル: tc_packets_module.c プロジェクト: TerryTsui/tcpcopy
static void 
send_packets_from_pcap(int first)
{
    int                 l2_len, ip_pack_len, p_valid_flag = 0;
    bool                stop;
    pcap_t             *pcap;
    unsigned char      *pkt_data, *frame, *ip_data;
    struct pcap_pkthdr  pkt_hdr;  

    pcap = clt_settings.pcap;

    if (pcap == NULL) {
        return;
    }

    gettimeofday(&cur_time, NULL);

    stop = check_read_stop();

    while (!stop) {

        pkt_data = (u_char *) pcap_next(pcap, &pkt_hdr);
        if (pkt_data != NULL) {

            if (pkt_hdr.caplen < pkt_hdr.len) {

                tc_log_info(LOG_WARN, 0, "truncated packets,drop");
            } else {

                ip_data = get_ip_data(clt_settings.pcap, pkt_data, 
                        pkt_hdr.len, &l2_len);
                if (l2_len < ETHERNET_HDR_LEN) {
                    tc_log_info(LOG_WARN, 0, "l2 len is %d", l2_len);
                    continue;
                }

                last_pack_time = pkt_hdr.ts;
                if (ip_data != NULL) {
                    clt_settings.pcap_time = last_pack_time.tv_sec * 1000 + 
                        last_pack_time.tv_usec / 1000; 

                    ip_pack_len = pkt_hdr.len - l2_len;
                    tc_log_debug2(LOG_DEBUG, 0, "frame len:%d, ip len:%d",
                            pkt_hdr.len, ip_pack_len);
                    frame = ip_data - ETHERNET_HDR_LEN;
                    dispose_packet(frame, ip_pack_len + ETHERNET_HDR_LEN,
                            ip_pack_len, &p_valid_flag);
                    if (p_valid_flag) {

                        tc_log_debug0(LOG_DEBUG, 0, "valid flag for packet");

                        if (first) {
                            first_pack_time = pkt_hdr.ts;
                            first = 0;
                        } else {
                            adj_v_pack_diff = timeval_diff(&last_v_pack_time,
                                    &last_pack_time);
                        }

                        /* set last valid packet time in pcap file */
                        last_v_pack_time = last_pack_time;

                        stop = check_read_stop();

                    } else {
                        tc_log_debug0(LOG_DEBUG, 0, "invalid flag");
                    }
                }
            }
        } else {

            tc_log_info(LOG_WARN, 0, "stop, null from pcap_next");
            stop = true;
            read_pcap_over = true;
            read_pcap_over_time = tc_time();
        }
    }
}