示例#1
0
/* Update router table */
void
router_update(tc_ip_header_t *ip_header, int len)
{
    void                   *fd;
    uint32_t                size_ip;
    uint64_t                key;
    msg_server_t            msg;
    struct tcphdr          *tcp_header;

    size_ip    = ip_header->ihl << 2;
    tcp_header = (struct tcphdr*)((char *)ip_header + size_ip);

    memcpy(&msg, ip_header, len);

    key = get_key(ip_header->daddr, tcp_header->dest);

    pthread_mutex_lock(&mutex);

    fd  = hash_find(table, key);
    if ( NULL == fd ) {
        tc_log((LOG_DEBUG), 0, "fd is null");
        delay_table_add(key, &msg);

        pthread_mutex_unlock(&mutex);

        return ;
    }

    pthread_mutex_unlock(&mutex);

    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
}
示例#2
0
/* send delayed message according to the key */
void
delay_table_send(uint64_t key, int fd)
{
    link_list           *msg_list;
    p_link_node          first;
    msg_server_t        *msg ;

    msg_list = (link_list *) hash_find(table, key);
    if (msg_list == NULL) {
        return; 
    }

    while (!link_list_is_empty(msg_list)) {
        first = link_list_pop_first(msg_list);
        msg = (first->data);

#if (INTERCEPT_COMBINED)
        buffer_and_send(fd, fd, msg);
#else
        tc_socket_send(fd, (char *) msg, MSG_SERVER_SIZE);
#endif
        msg_delay_sent_cnt++;

        msg_item_free_cnt++;
        link_node_internal_free(first);
        free(first);
    }

}
示例#3
0
/* Update router table */
void
router_update(struct iphdr *ip_header)
{
    void                   *fd;
    uint32_t                size_ip;
    uint64_t                key;
    msg_server_t            msg;
    struct tcphdr          *tcp_header;
#if (TCPCOPY_MYSQL_ADVANCED) 
    uint32_t                size_tcp, cont_len, tot_len;
    unsigned char          *payload;
#endif

    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    size_ip = ip_header->ihl << 2;
    tcp_header = (struct tcphdr*)((char *)ip_header + size_ip);

    memset(&msg, 0, sizeof(struct msg_server_s));
    memcpy((void *) &(msg.ip_header),  ip_header,  sizeof(struct iphdr));
    memcpy((void *) &(msg.tcp_header), tcp_header, sizeof(struct tcphdr));

#if (TCPCOPY_MYSQL_ADVANCED) 
    tot_len  = ntohs(ip_header->tot_len);
    size_tcp = tcp_header->doff << 2;
    cont_len = tot_len - size_ip - size_tcp;
    if (cont_len > 0) {
        payload = (unsigned char*)((char*)tcp_header + size_tcp);
        if (cont_len <= MAX_PAYLOAD_LEN) {
            /*
             * Only transfer payload if content length is less
             * than MAX_PAYLOAD_LEN
             */
            memcpy((void *) &(msg.payload), payload, cont_len);
        }
    }
#endif

    key = get_key(ip_header->daddr, tcp_header->dest);
    fd  = hash_find(table, key);
    if ( NULL == fd ) {
        tc_log_debug0(LOG_DEBUG, 0, "fd is null");
        delay_table_add(key, &msg);
        return ;
    }

    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
}
示例#4
0
static bool send_version(int fd) {
    msg_client_t    msg;

    memset(&msg, 0, sizeof(msg_client_t));
    msg.client_ip = htonl(0);
    msg.client_port = htons(0);
    msg.type = htons(INTERNAL_VERSION);

    if (tc_socket_send(fd, (char *) &msg, MSG_CLIENT_SIZE) == TC_ERROR) {
        tc_log_info(LOG_ERR, 0, "send version error:%d", fd);
        return false;
    }

    return true;
}
示例#5
0
static bool
send_router_info(tc_user_t *u, uint16_t type)
{
    int                      i, fd;
    bool                     result = false;
    msg_client_t             msg;
    connections_t           *connections;


    memset(&msg, 0, sizeof(msg_client_t));
    msg.client_ip = u->src_addr;
    msg.client_port = u->src_port;
    msg.type = htons(type);
    msg.target_ip = u->dst_addr;
    msg.target_port = u->dst_port;

    for (i = 0; i < clt_settings.real_servers.num; i++) {

        if (!clt_settings.real_servers.active[i]) {
            continue;
        }

        connections = &(clt_settings.real_servers.connections[i]);
        fd = connections->fds[connections->index];
        connections->index = (connections->index + 1) % connections->num;

        if (fd == -1) {
            tc_log_info(LOG_WARN, 0, "sock invalid");
            continue;
        }

        if (tc_socket_send(fd, (char *) &msg, MSG_CLIENT_SIZE) == TC_ERROR) {
            tc_log_info(LOG_ERR, 0, "fd:%d, msg client send error", fd); 
            if (clt_settings.real_servers.active[i] != 0) {
                clt_settings.real_servers.active[i] = 0;
                clt_settings.real_servers.active_num--;
            }

            continue;
        }
        result = true;
    }                                                                                                             
    return result;
}
示例#6
0
void
buffer_and_send(int fd, msg_server_t *msg)
{
    int                ret = TC_OK, is_send = 0, bytes;
    unsigned char     *p;
    aggregation_t     *aggr;

    if (fd > srv_settings.max_fd) {
        srv_settings.max_fd = fd;
    }

    if (srv_settings.max_fd > MAX_FD_VALUE) {
        tc_log_info(LOG_WARN, 0, "fd is too large:%d", srv_settings.max_fd);
        srv_settings.max_fd = MAX_FD_VALUE;
        return;
    }

    if (!srv_settings.tunnel[fd].fd_valid) {
        tc_log_debug1(LOG_DEBUG, 0, "fd is not valid:%d", fd);
        return;
    }

    aggr = srv_settings.tunnel[fd].combined;
    if (!aggr) {
        aggr = (aggregation_t *) malloc(sizeof(aggregation_t));
        if (aggr == NULL) {
            tc_log_info(LOG_ERR, errno, "can't malloc memory");
        } else {
            tc_log_info(LOG_INFO, 0, "malloc memory for fd:%d", fd);
            memset(aggr, 0, sizeof(aggregation_t));
            aggr->cur_write = aggr->aggr_resp;
            srv_settings.tunnel[fd].combined = aggr;
        }
    }

    if (aggr) {
        if (msg != NULL) {
            p = aggr->cur_write;
            memcpy((char *) p, (char *) msg, MSG_SERVER_SIZE); 
            aggr->cur_write = p + MSG_SERVER_SIZE;
            aggr->num = aggr->num + 1;
        } else {
            if (aggr->num == 0) {
                return;
            }
        }

        if (aggr->num == COMB_MAX_NUM) {
            is_send = 1;
        } else if (aggr->access_time < tc_current_time_sec) {
            is_send = 1;
        } else if (aggr->access_time == tc_current_time_sec) {
            if (aggr->access_msec != tc_current_time_msec) {
                is_send = 1;
            }
        }

        if (is_send) {
            tc_log_debug1(LOG_DEBUG, 0, "combined send:%d", aggr->num);
            aggr->num = htons(aggr->num);
            p = (unsigned char *) (&(aggr->num));
            bytes = aggr->cur_write - aggr->aggr_resp + sizeof(aggr->num);
            tc_log_debug1(LOG_DEBUG, 0, "send bytes:%d", bytes);
            ret = tc_socket_send(fd, (char *) p, bytes);
            aggr->num = 0;
            aggr->cur_write = aggr->aggr_resp;
        } 

        aggr->access_time = tc_current_time_sec;
        aggr->access_msec = tc_current_time_msec;

        if (ret == TC_ERROR) {
            tc_intercept_release_tunnel(fd, NULL);
        }
    }
}
示例#7
0
void
buffer_and_send(int mfd, int fd, msg_server_t *msg)
{
    int                  ret = TC_OK, is_send = 0, bytes;
    unsigned char       *p;
    aggregation_t       *aggr;

#if (TCPCOPY_SINGLE)
    if (mfd == 0) {
        return;
    }
#endif

    if (fd > max_fd) {
        max_fd = fd;
    }

    if (max_fd > MAX_FD_VALUE) {
        tc_log_info(LOG_WARN, 0, "fd is too large:%d", max_fd);
        max_fd = MAX_FD_VALUE;
        return;
    }

    if (!fd_valid[fd]) {
        tc_log_debug1(LOG_DEBUG, 0, "fd is not valid:%d", fd);
        return;
    }

    aggr = combined[fd];
    if (!aggr) {
        aggr = (aggregation_t *) malloc(sizeof(aggregation_t));
        if (aggr == NULL) {
            tc_log_info(LOG_ERR, errno, "can't malloc memory");
        } else {
            tc_log_info(LOG_INFO, 0, "malloc memory for fd:%d", fd);
            memset(aggr, 0, sizeof(aggregation_t));
            aggr->cur_write = aggr->aggr_resp;
            combined[fd] = aggr;
        }
    }

    if (aggr) {
        if (msg != NULL) {
            p = aggr->cur_write;
            memcpy((char *) p, (char *) msg, MSG_SERVER_SIZE); 
            aggr->cur_write = p + MSG_SERVER_SIZE;
            aggr->num = aggr->num + 1;
        } else {
            if (aggr->num == 0) {
                tc_log_debug0(LOG_DEBUG, 0, "combined num is zero");
                return;
            }
        }

        if (aggr->num == COMB_MAX_NUM) {
            is_send = 1;
        } else if (aggr->access_time < tc_current_time_sec) {
            is_send = 1;
        } else if (aggr->access_time == tc_current_time_sec) {
            if (aggr->access_msec != tc_current_time_msec) {
                is_send = 1;
            }
        }

        if (is_send) {
            tc_log_debug1(LOG_DEBUG, 0, "combined send:%d", aggr->num);
            aggr->num = htons(aggr->num);
            p = (unsigned char *) (&(aggr->num));
            bytes = aggr->cur_write - aggr->aggr_resp + sizeof(aggr->num);
            tc_log_debug1(LOG_DEBUG, 0, "send bytes:%d", bytes);
#if (!TCPCOPY_SINGLE)
            ret = tc_socket_send(fd, (char *) p, bytes);
#else
            ret = tc_socket_send(mfd, (char *) p, bytes);
#endif
            aggr->num = 0;
            aggr->cur_write = aggr->aggr_resp;
        } 

        aggr->access_time = tc_current_time_sec;
        aggr->access_msec = tc_current_time_msec;

        if (ret == TC_ERROR) {
            fd_valid[fd] = false;
            free(combined[fd]);
            combined[fd] = NULL;
        }
    }
}
示例#8
0
void
router_update(int main_router_fd, tc_ip_header_t *ip_header)
{
#if (!TCPCOPY_SINGLE)
    void                   *fd;
    uint64_t                key;
#endif
    uint32_t                size_ip, size_tcp, new_size_tcp;
    msg_server_t            msg;
    tc_tcp_header_t        *tcp_header;
#if (TCPCOPY_MYSQL_ADVANCED)
    uint32_t                cont_len, tot_len, new_tot_len;
    unsigned char          *payload, *p;
#endif

#if (TCPCOPY_SINGLE)
    if (main_router_fd == 0) {
        return;
    }
#endif
    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    size_ip = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);
    size_tcp = tcp_header->doff << 2;
#if (TCPCOPY_MYSQL_ADVANCED)
    tot_len  = ntohs(ip_header->tot_len);
#endif

    memset(&msg, 0, sizeof(struct msg_server_s));

    new_size_tcp = size_tcp;
    if (size_tcp > TCP_HEADER_MIN_LEN) {
        set_wscale(tcp_header);
        new_size_tcp = tcp_header->doff << 2;
#if (TCPCOPY_MYSQL_ADVANCED)
        new_tot_len = tot_len - (size_tcp - new_size_tcp);
        ip_header->tot_len = htons(new_tot_len);
#endif
    }
    memcpy((void *) &(msg.ip_header), ip_header, sizeof(tc_ip_header_t));
    memcpy((void *) &(msg.tcp_header), tcp_header, new_size_tcp);

#if (TCPCOPY_MYSQL_ADVANCED)
    cont_len = tot_len - size_ip - size_tcp;
    if (cont_len > 0) {
        payload = (unsigned char *) ((char *) tcp_header + size_tcp);
        if (cont_len <= MAX_PAYLOAD_LEN) {
            p = ((unsigned char *) &(msg.tcp_header)) + new_size_tcp;
            /*
             * only transfer payload if content length is less
             * than MAX_PAYLOAD_LEN
             */
            memcpy((void *) p, payload, cont_len);
        }
    }
#endif
#if (!TCPCOPY_SINGLE)
    key = get_key(ip_header->daddr, tcp_header->dest);
    fd  = hash_find(table, key);
    if (fd == NULL) {
        if (!tcp_header->syn) {
            tc_log_info(LOG_NOTICE, 0, "fd is null after session is created");
            tc_log_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);
        }
        tc_log_debug0(LOG_DEBUG, 0, "fd is null");
        fd_null_cnt++;
        delay_table_add(key, &msg);
        return ;
    }
#endif

    tc_log_debug_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);

#if (INTERCEPT_COMBINED)

#if (!TCPCOPY_SINGLE)
    buffer_and_send(main_router_fd, (int) (long) fd, &msg);
#else
    buffer_and_send(main_router_fd, main_router_fd, &msg);
#endif

#else

#if (!TCPCOPY_SINGLE)
    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
#else
    tc_socket_send(main_router_fd, (char *) &msg, MSG_SERVER_SIZE);
#endif

#endif

}
示例#9
0
/* update router table */
void
router_update(int main_router_fd, tc_ip_header_t *ip_header, int len)
{
#if (!TCPCOPY_SINGLE)
    void                   *fd;
    uint64_t                key;
#endif
    uint32_t                size_ip;
    msg_server_t            msg;
    tc_tcp_header_t        *tcp_header;

#if (TCPCOPY_SINGLE)
    if (main_router_fd == 0) {
        return;
    }
#endif
    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    size_ip    = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);

    tc_log_debug1(LOG_DEBUG, 0, "router update:%u", ntohs(tcp_header->source));
    memcpy(&msg, ip_header, len);

#if (!TCPCOPY_SINGLE)
    key = get_key(ip_header->daddr, tcp_header->dest);
    pthread_mutex_lock(&mutex);

    fd  = hash_find(table, key);
    if (fd == NULL) {
        if (!tcp_header->syn) {
            tc_log_info(LOG_NOTICE, 0, "fd is null after session is created");
            tc_log_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header); 
        }
        tc_log_debug0(LOG_DEBUG, 0, "fd is null");
        fd_null_cnt++;
        delay_table_add(key, &msg);

        pthread_mutex_unlock(&mutex);

        return ;
    }

    pthread_mutex_unlock(&mutex);
#endif

    tc_log_debug_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);

#if (INTERCEPT_COMBINED)

#if (!TCPCOPY_SINGLE)
    buffer_and_send(main_router_fd, (int) (long) fd, &msg);
#else
    buffer_and_send(main_router_fd, main_router_fd, &msg);
#endif

#else

#if (!TCPCOPY_SINGLE)
    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
#else
    tc_socket_send(main_router_fd, (char *) &msg, MSG_SERVER_SIZE);
#endif

#endif

}
示例#10
0
文件: tc_router.c 项目: cnJun/tcpcopy
void
router_update(int old, int main_router_fd, tc_ip_header_t *ip_header)
{
#if (!TCPCOPY_SINGLE)
    int                     fd;
    uint32_t                key;
#endif
    uint32_t                size_ip, size_tcp, tot_len;
    msg_server_t            msg;
    tc_tcp_header_t        *tcp_header;
#if (TCPCOPY_MYSQL_ADVANCED)
    uint32_t                cont_len;
    unsigned char          *payload, *p;
#endif
#if (TCPCOPY_SINGLE)
    if (main_router_fd == 0) {
        return;
    }
#endif
    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    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);

    memset(&msg, 0, sizeof(struct msg_server_s));
    memcpy((void *) &(msg.ip_header), ip_header, sizeof(tc_ip_header_t));
    memcpy((void *) &(msg.tcp_header), tcp_header, size_tcp);

#if (TCPCOPY_MYSQL_ADVANCED)
    cont_len = tot_len - size_ip - size_tcp;
    if (cont_len > 0) {
        payload = (unsigned char *) ((char *) tcp_header + size_tcp);
        if (cont_len <= MAX_PAYLOAD_LEN) {
            p = ((unsigned char *) &(msg.tcp_header)) + size_tcp;
            memcpy((void *) p, payload, cont_len);
        }
    }
#endif 
#if (!TCPCOPY_SINGLE)
    key = get_route_key(old, ip_header->daddr, tcp_header->dest, 
            ip_header->saddr, tcp_header->source);
    fd  = router_get(key);
    if (fd <= 0) {
        if (tcp_header->syn || tcp_header->rst) {
            if (tcp_header->rst) {
                tc_log_info(LOG_NOTICE, 0, "reset from tcp");
            } 
            tc_log_debug0(LOG_DEBUG, 0, "fd is null");
            delay_table_add(key, &msg);
            return ;
        } else {
            tc_log_info(LOG_NOTICE, 0, "fd is null after session is created");
            tc_log_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);
            return;
        }
    }
#endif

    tc_log_debug_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);

#if (INTERCEPT_COMBINED)

#if (!TCPCOPY_SINGLE)
    buffer_and_send(main_router_fd, (int) (long) fd, &msg);
#else
    buffer_and_send(main_router_fd, main_router_fd, &msg);
#endif                       
#else

#if (!TCPCOPY_SINGLE)
    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
#else
    tc_socket_send(main_router_fd, (char *) &msg, MSG_SERVER_SIZE);
#endif

#endif

}