From 86a43b4d325ddc850fa9dc4711670880f35b11e8 Mon Sep 17 00:00:00 2001 From: lijia Date: Wed, 24 Oct 2018 09:36:45 +0800 Subject: create new project. --- src/packet_io/flwd_packet_io_socket.c | 376 ++++++++++++++++++++++++++++++++++ 1 file changed, 376 insertions(+) create mode 100644 src/packet_io/flwd_packet_io_socket.c (limited to 'src/packet_io/flwd_packet_io_socket.c') diff --git a/src/packet_io/flwd_packet_io_socket.c b/src/packet_io/flwd_packet_io_socket.c new file mode 100644 index 0000000..6dad448 --- /dev/null +++ b/src/packet_io/flwd_packet_io_socket.c @@ -0,0 +1,376 @@ +#include "flowood.h" +#include "flowood_fun.h" +#include "flwd_net.h" +#include +#include "MESA_list_queue.h" +#include "MESA_handle_logger.h" +#include "MESA_prof_load.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +/* 需要动态dlopen获取符号名, 使用C规范 */ +extern "C" { +#endif + + +typedef struct { + pthread_t pid; + unsigned char thread_seq; + int sd; /* socket句柄, UDP层, DGRAM模式 */ + struct sockaddr sock_addr; +}socket_work_thread_t; + +typedef struct{ + char *__data_buf; /* mbuff缓冲区头指针 */ + char *data_actual_ptr; /* 当前缓存实际存储的数据指针, 从MAC开始,没有也有预留空间伪造一个, 比如socket模式 */ + int __data_buf_max_len; /* mbuff最大缓存长度, 即FLWD_LINK_MTU */ + int data_actual_len; /* 当前缓存中实际存储的数据长度 */ +}socket_mbuff_t; + +/* pcap模式内部句柄结构 */ +typedef struct{ + int tot_thread_count; + int *socket_dev_handle; /* sd句柄的指针 */ + socket_work_thread_t socket_io_thread_para[FLWD_MAX_THREAD_NUM]; + socket_mbuff_t socket_send_buf[FLWD_MAX_THREAD_NUM]; /* 发包缓存, 初始化时申请, 以后发包不用每次动态malloc/free */ +}flwd_device_handle_socket_t; + + + +/* 此函数可以阻塞或死循环, 一直不返回 */ +void low_level_io_run(flwd_device_handle_t *global_io_handle) +{ + /* socket模式, init成功后, 不需调用其他接口, 直接recv, send即可 */ + (void )global_io_handle; + + return; +} + + +static socket_mbuff_t *flwd_socket_create_new_mbuff(int datalen) +{ + socket_mbuff_t *sock_mbuff; + + sock_mbuff = (socket_mbuff_t *)calloc(1, sizeof(socket_mbuff_t)); + + sock_mbuff->__data_buf = (char *)malloc(datalen + FLWD_VXLAN_OUTER_PACKET_LEN); /* 预留vxlan头部 */ + sock_mbuff->__data_buf_max_len = datalen + FLWD_VXLAN_OUTER_PACKET_LEN; + + + sock_mbuff->data_actual_ptr = sock_mbuff->__data_buf + FLWD_VXLAN_OUTER_PACKET_LEN; + sock_mbuff->data_actual_len = datalen; + + return sock_mbuff; +} + +/* socket addr_para: addr_para=127.0.0.1:50000 */ +int flwd_socket_addr_para_parse(char *cfg_line, unsigned int *sock_addr_ip_net_order, unsigned short *sock_addr_port_host_order) +{ + const char *delim = ": "; + char *save_ptr; + char *section; + int tmp; + + section = strtok_r(cfg_line, delim, &save_ptr); + if(inet_pton(AF_INET, cfg_line, sock_addr_ip_net_order) <= 0){ + return -1; + } + + section = strtok_r(NULL, delim, &save_ptr); + if(NULL == section){ + return -1; + } + + tmp = atoi(section); + if(tmp <= 0 || tmp > 65535){ + return -1; + } + + *sock_addr_port_host_order = (unsigned short)tmp; + + while(strtok_r(NULL, delim, &save_ptr)); + + return 0; +} + +/* 为了gdb设断点方便, 每种io_lib有自己内部独特的函数名称 */ +static int socket_low_level_io_init(flwd_device_handle_t *global_dev_handle) +{ + int i, tmp_int; + char str_tmp[128]; + unsigned int sock_addr_ip_net_order = 0; /* socket模式绑定任意IP */ + unsigned short sock_addr_port_host_order; /* 起始端口, 一共绑定从当前端口开始到port + thread_count */ + struct sockaddr_in sockadd; + + flwd_device_handle_socket_t *socket_io_handle = (flwd_device_handle_socket_t *)calloc(1, sizeof(flwd_device_handle_socket_t)); + + /* socket addr_para: addr_para=60000, 表示本地绑定的起始端口, 以及后续的thread_num个连续端口 */ + MESA_load_profile_string_def(FLWD_CONFIG_FILE, g_packet_io_cfg_para[(int)global_dev_handle->io_para.topo_mode].cfg_file_section, "addr_para", str_tmp, 128, "#"); + if('#' == str_tmp[0]){ + flwd_log(RLOG_LV_FATAL, "get config %s->addr_para error!", g_packet_io_cfg_para[(int)global_dev_handle->io_para.topo_mode].cfg_file_section); + return -1; + } + +#if 0 + ret = flwd_socket_addr_para_parse(str_tmp, &sock_addr_ip_net_order, &sock_addr_port_host_order); + if(ret < 0){ + flwd_log(RLOG_LV_FATAL, "parse config %s->addr_para %s error!", + g_packet_io_cfg_para[(int)global_dev_handle->io_para.topo_mode].cfg_file_section, str_tmp); + return -1; + } +#else + tmp_int = atoi(str_tmp); + if((tmp_int <= 0) || (tmp_int > 65535)){ + flwd_log(RLOG_LV_FATAL, "%s config %s->addr_para error!", g_packet_io_cfg_para[(int)global_dev_handle->io_para.topo_mode].cfg_file_section); + return -1; + } +#endif + + sock_addr_port_host_order = (unsigned short)tmp_int; + + for(i = 0; i < global_dev_handle->tot_thread_count; i++){ + socket_io_handle->socket_io_thread_para[i].thread_seq = i; + socket_io_handle->socket_send_buf[i].__data_buf = (char *)malloc(FLWD_LINK_MTU); + socket_io_handle->socket_send_buf[i].__data_buf_max_len = FLWD_LINK_MTU; + socket_io_handle->socket_io_thread_para[i].sd = socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&sockadd, sizeof(sockadd)); + sockadd.sin_family = AF_INET; + sockadd.sin_addr.s_addr = sock_addr_ip_net_order; + sockadd.sin_port = htons(sock_addr_port_host_order + i); + + if(bind(socket_io_handle->socket_io_thread_para[i].sd, (struct sockaddr *) &sockadd, sizeof(sockadd)) < 0){ + flwd_log(RLOG_LV_FATAL, "Socket bind port %u error, %s!\n", sock_addr_port_host_order + i, strerror(errno)); + return -1; + } + } + + global_dev_handle->io_para.device_ip_net_order = sock_addr_ip_net_order; + global_dev_handle->io_para.socket_port_net_order = htons(sock_addr_port_host_order); + + socket_io_handle->tot_thread_count = global_dev_handle->tot_thread_count; + global_dev_handle->low_level_io_handle = (void *)socket_io_handle; + + return 0; +} + +#if FLWD_NAT_SPORT_VOLATILE +static struct sockaddr_in g_remote_addr; +#endif + + +static int socket_low_level_send(flwd_device_handle_t *global_dev_handle, int tid, void *mbuff) +{ + int ret; + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + flwd_device_handle_socket_t *sock_io_handle = (flwd_device_handle_socket_t *)global_dev_handle->low_level_io_handle; + struct sockaddr_in sockadd; + const flwd_ipv4_hdr_t *ipv4_hdr = (flwd_ipv4_hdr_t *) (sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t)); + const flwd_udp_hdr_t *udph = (flwd_udp_hdr_t *)(sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t)); + + sockadd.sin_family = AF_INET; + +#if FLWD_NAT_SPORT_VOLATILE + sockadd.sin_addr.s_addr = g_remote_addr.sin_addr.s_addr; + sockadd.sin_port = g_remote_addr.sin_port; +#else + sockadd.sin_addr.s_addr = ipv4_hdr->ip_dst.s_addr; + sockadd.sin_port = udph->uh_dport; +#endif + + ret = sendto(sock_io_handle->socket_io_thread_para[tid].sd, + sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t) + sizeof(flwd_udp_hdr_t), /* 上层应用都默认从mac层开始, 此处使用socket模式, 系统会封装MAC,IP,UDP, 跳过鍁xlan外层的MAC头+ip头+udp头 */ + sock_mbuff->data_actual_len - sizeof(flwd_eth_hdr_t) - sizeof(flwd_ipv4_hdr_t) - sizeof(flwd_udp_hdr_t), /* 上层应用都默认从mac层开始, 此处使用socket模式, 系统会封装MAC,IP,UDP, 跳过vxlan外层的MAC头+ip头+udp头 */ + MSG_DONTWAIT, + (const struct sockaddr *)&sockadd, + sizeof(struct sockaddr)); + + return ret; +} + +int low_level_pkt_recv(flwd_device_handle_t *g_dev_handle, int tid, void **mbuff) +{ + int ret; + socket_mbuff_t *sock_mbuff; + char sock_rcv_buf[FLWD_LINK_MTU]; + flwd_device_handle_socket_t *socket_io_handle = (flwd_device_handle_socket_t *)g_dev_handle->low_level_io_handle; + flwd_eth_hdr_t *ehdr; + flwd_ipv4_hdr_t *ipv4_hdr; + struct sockaddr_in local_remote_addr; + socklen_t addr_len = sizeof(local_remote_addr); + + ret = recvfrom(socket_io_handle->socket_io_thread_para[tid].sd, sock_rcv_buf, FLWD_LINK_MTU, MSG_DONTWAIT, (struct sockaddr *)&local_remote_addr, &addr_len); + + if(ret > 0){ + sock_mbuff = flwd_socket_create_new_mbuff(ret + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t) + sizeof(flwd_udp_hdr_t)); + + /* 伪造一个mac开始的原始包, 模拟vxlan外层ethernet */ + ehdr = (flwd_eth_hdr_t *)(sock_mbuff->data_actual_ptr); + ehdr->h_proto = htons(ETH_P_IP); + + /* 模拟vxlan外层ipv4 */ + ipv4_hdr = (flwd_ipv4_hdr_t *) (sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t)); + ipv4_hdr->ip_v = 4; + ipv4_hdr->ip_hl = 5; + ipv4_hdr->ip_p = IPPROTO_UDP; + + /* 把udp收到的数据预留头部空间, 再拷贝 */ + memcpy(sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t) + sizeof(flwd_udp_hdr_t), sock_rcv_buf, ret); + sock_mbuff->data_actual_len = ret + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t) + sizeof(flwd_udp_hdr_t); + + +#if FLWD_NAT_SPORT_VOLATILE + if(memcmp(&local_remote_addr, &g_remote_addr, sizeof(local_remote_addr)) != 0){ + /* 因为NAT内部的主机发包很少, 导致出NAT后的源端口变了 */ + memcpy(&g_remote_addr, &local_remote_addr,sizeof(local_remote_addr)); + } +#endif + + + }else{ + *mbuff = NULL; + return -1; + } + + *mbuff = (void *)sock_mbuff; + + return ret; +} + +void low_level_pkt_free(flwd_device_handle_t *g_dev_handle, int tid, void *mbuff) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + free(sock_mbuff->__data_buf); + free(sock_mbuff); + + return; +} + +void *low_level_mbuff_malloc(flwd_device_handle_t *g_dev_handle, int tid, int len) +{ + //flwd_device_handle_socket_t *socket_io_handle = (flwd_device_handle_socket_t *)g_dev_handle->low_level_io_handle; + + socket_mbuff_t *mbuff = (socket_mbuff_t *)malloc(sizeof(socket_mbuff_t)); + + mbuff->__data_buf = (char *)malloc(FLWD_LINK_MTU); + mbuff->data_actual_ptr = mbuff->__data_buf + FLWD_VXLAN_OUTER_PACKET_LEN; + mbuff->__data_buf_max_len = FLWD_LINK_MTU; + mbuff->data_actual_len = 0; + + return (void *)mbuff; +} + +char *low_level_mbuff_mtod(void *mbuff) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + return (char *)sock_mbuff->data_actual_ptr; +} + +void low_level_mbuff_free(struct __flwd_device_handle *h, int tid, void *mbuff) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + free(sock_mbuff->__data_buf); + sock_mbuff->data_actual_len = 0; + sock_mbuff->__data_buf_max_len = 0; + free(mbuff); +} + +void low_level_mbuff_free_after_send(flwd_device_handle_t *g_dev_handle, int tid, void *mbuff) +{ + /* pcap模式发送无自动free, 再次调用真正的free函数 */ + low_level_mbuff_free(g_dev_handle, tid, mbuff); +} + +void low_level_mbuff_send_back(flwd_device_handle_t *g_dev_handle, int tid, void *mbuff) +{ + /* socket模式暂时不用回注gdev数据包, 空函数 */ + return; +} + +/* + 在mbuff里追加user_data数据. + return value: + 数据起始位置; +*/ +char * low_level_mbuff_data_append(void *mbuff, const char *user_data, int user_data_len) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + assert(user_data_len <= sock_mbuff->__data_buf_max_len - sock_mbuff->data_actual_len); + + memcpy(sock_mbuff->data_actual_ptr, user_data, user_data_len); + sock_mbuff->data_actual_len += user_data_len; + + return (char *)sock_mbuff->data_actual_ptr; +} + +/* 数据指针向前移动N个字节, 数据长度自动增加N, 功能是在现有数据包之前填充其他包头, 预留一些空间, 如vxlan */ +char * low_level_mbuff_data_forward(void *mbuff, int n) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + assert(n <= sock_mbuff->data_actual_ptr - sock_mbuff->__data_buf); + + sock_mbuff->data_actual_ptr -= n; + sock_mbuff->data_actual_len += n; + + return (char *)sock_mbuff->data_actual_ptr; +} + + +/* 数据指针向后移动N个字节, 数据长度自动减少N, 功能是把现有数据包的某些包头跳过, 如剥去vxlan头部 */ +char * low_level_mbuff_data_rearward(void *mbuff, int n) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + assert(n <= sock_mbuff->__data_buf_max_len - sock_mbuff->data_actual_len); + + sock_mbuff->data_actual_ptr += n; + sock_mbuff->data_actual_len -= n; + + return sock_mbuff->data_actual_ptr; +} + + +int low_level_mbuff_get_pkt_len(void *mbuff) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + return sock_mbuff->data_actual_len; +} + +void low_level_mbuff_set_pkt_len(void *mbuff, int pkt_len) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + sock_mbuff->data_actual_len = pkt_len; +} + + +int low_level_send(flwd_device_handle_t *global_dev_handle, int tid, void *mbuff) +{ + return socket_low_level_send(global_dev_handle, tid, mbuff); +} + + +int low_level_io_init(flwd_device_handle_t *global_dev_handle) +{ + return socket_low_level_io_init(global_dev_handle); +} + +#ifdef __cplusplus +} +#endif + -- cgit v1.2.3