📄 lcm_rsock.c
字号:
#ifdef __cplusplusextern "C"{#endif #include "syscfg.h"#if( CONFIG_BOARD_GMPU == TRUE || CONFIG_BOARD_EIA == TRUE )#include "aos.h"#include "ifnet/if_pub.h"#include "ip/ip_pub.h"#include "rtp_pub.h"#include "cli/cli_pub.h"#include "p2p_include.h"#include "nat/nat_pub.h"#include "p2p_include.h"#define RSOCK_HASH_MASK 511#define RSOCK_HASH_NUM 512#define RSOCK_HASHFUNC(usFPort, ulFAddr) \ (U16) (((usFPort) ^ \ ((U16)((U32)(ulFAddr)>>16)) ^ \ ((U16)(ulFAddr))) & \ RSOCK_HASH_MASK )#if (AOS_INCLUDE_SERVICE_P2P_SN_CN == TRUE)#define MAX_RSOCK_NUM 40000#elif (CONFIG_BOARD_GMPU == TRUE )#define MAX_RSOCK_NUM 25000#else#define MAX_RSOCK_NUM 1000#endif#define RSOCK_SYN_SEND_TIMER 0 #define RSOCK_SYN_RECV_TIMER 1 #define RSOCK_WAIT_REF_TIMER 2 #define RSOCK_GLOBAL_WAIT_REF_TIMER 3 #define RSOCK_FREE_PORT_TIMER 4 #define RSOCK_SYN_SEND_TIMER_LEN 500 #define RSOCK_SYN_RECV_TIMER_LEN 10000 #define RSOCK_WAIT_REF_TIMER_LEN 10000 #define RSOCK_FREE_PORT_BASE 8192 #define RSOCK_FREE_PORT_NUM 8192 #define RSOCK_UDP_FREE_PORT_NUM 1024 #define RSOCK_TCP_PORT_ARY_NUM (RSOCK_FREE_PORT_NUM/32)#define RSOCK_TCP_PORT_ARY_MASK (RSOCK_FREE_PORT_NUM/32 -1)#define RSOCK_UDP_PORT_ARY_NUM (RSOCK_UDP_FREE_PORT_NUM/32)#define RSOCK_UDP_PORT_ARY_MASK (RSOCK_UDP_FREE_PORT_NUM/32 -1)#define RSOCK_TCP_PORT_FREE_TIME 125 typedef struct rsock_s{ U8 init:1; U8 connected:1; U8 seq_init:1; U8 is_tcp_server:1; U8 alloc_flag:1; U8 proto:3; U8 tcp_state; U16 ref; U32 peer_ip; U16 peer_port; U16 lcl_port; U32 tcp_seq; U32 tcp_ack; U32 tcp_last_ack;#if( CONFIG_BOARD_GMPU == TRUE ) U32 if_index;#endif TMR tcp_tmr; struct aos_list rsock_next;}rsock_t;typedef struct lcm_port_s{ struct aos_list node; U16 usPort; U16 expire; }lcm_port_t;rsock_t *g_pstRsock = NULL;struct aos_list g_FreeRsockList;struct aos_list g_RsockHashList4Udp[RSOCK_HASH_NUM];struct aos_list g_RsockHashList4Tcp[RSOCK_HASH_NUM];U32 g_ulRsockDbgFlag = 1;U32 g_ulRsockProtectNum1;U32 g_ulRsockProtectNum2;U32 g_ulRsockDbgIpFilter = 0;U32 g_ulRsockIpRefreshShowFlag = 0;enum enRsockState{ RSOCK_STATE_INIT = 0, RSOCK_STATE_SYN_SEND = 1, RSOCK_STATE_SYN_RECV = 2, RSOCK_STATE_ESTABLISHED = 3, RSOCK_STATE_BUTT};S8 *g_astRsockStateStr[] = { "init", "syn-send", "syn-recv", "estb"};U32 g_pRsockInitFlag=0;U32 *g_pTcpPortAllocFlag;U32 g_ulTcpPortAllocPos;U32 g_ulUdpPortAllocPosX,g_ulUdpPortAllocPosY;U32 g_UdpPortAllocFlag[RSOCK_UDP_PORT_ARY_NUM];struct aos_list g_stLcmPortWaitFreeList;U32 g_ulLcmPortWaitFreeCnt;U16 g_usRsockBasePort;#if( CONFIG_BOARD_GMPU == TRUE )U32 g_ulRsGateWay[SERVICE_ETHNET_PORT+1] = {0,0};#endifVOID rsock_timer( U32 name, U32 para );VOID rsock_free( rsock_t *rs );S8 *rsock_get_tcp_signal( U8 flags );VOID rsock_debug_proc( U32 cmd, U32 para );U16 rsock_alloc_tcp_port();U16 rsock_alloc_udp_port();VOID rsock_free_tcp_port( U16 usPort );VOID rsock_free_udp_port( U16 usPort );VOID rsock_port_expire();AOS_INLINE U16 rsock_base_port();extern U16 g_usIpId;extern IPSTAT_S g_stIpStat;extern VOID rt_alloc(ROUTE_S *pRo);extern void clear_watch_dog(void);extern U32 rand(VOID) ;#if( CONFIG_OS_VXWORKS == TRUE )#if ( CONFIG_BOARD_GMPU == TRUE || defined(_EIA2000V7) )#define TXRX_INTERUPPT_ENABLE TRUE#endifextern int intCount (void);#endifU32 rsock_init_proc( START_ORDER_E order ){ U32 r;#if( CONFIG_BOARD_GMPU == TRUE ) S8 szIpStr[64]; U32 ulIpAddr;#endif switch( order ) { case STARTUP_BEFORE_INITIAL: g_pRsockInitFlag = 0; break; case STARTUP_INITIAL: g_usRsockBasePort = RSOCK_FREE_PORT_BASE; aos_list_init(&g_stLcmPortWaitFreeList); g_ulLcmPortWaitFreeCnt = 0; g_ulTcpPortAllocPos = (rand()%RSOCK_FREE_PORT_NUM); g_ulUdpPortAllocPosX = 0; g_ulUdpPortAllocPosY = 0; g_pTcpPortAllocFlag = (U32*)aos_smem_alloc( MPE_RSOCK, 100, sizeof(U32)*RSOCK_TCP_PORT_ARY_NUM ); if( NULL == g_pTcpPortAllocFlag ) { return AOS_FAIL; } aos_memset(g_pTcpPortAllocFlag,0,sizeof(U32)*RSOCK_TCP_PORT_ARY_NUM); aos_memset(g_UdpPortAllocFlag, 0, sizeof(g_UdpPortAllocFlag) ); g_pstRsock = (rsock_t*)aos_smem_alloc( MPE_RSOCK, 101, sizeof(rsock_t)*MAX_RSOCK_NUM ); if( NULL == g_pstRsock ) { return AOS_FAIL; } aos_memset( g_pstRsock, 0, sizeof(rsock_t)*MAX_RSOCK_NUM ); aos_list_init( &g_FreeRsockList ); for( r = 0; r < MAX_RSOCK_NUM; r++ ) { aos_list_add_tail( &g_FreeRsockList, &g_pstRsock[r].rsock_next ); } for( r = 0; r < RSOCK_HASH_NUM; r++ ) { aos_list_init( &g_RsockHashList4Udp[r] ); aos_list_init( &g_RsockHashList4Tcp[r] ); } g_ulRsockDbgFlag = 0; g_ulRsockProtectNum1 = 0; g_ulRsockProtectNum2 = 0; break; case STARTUP_LOAD_DATA: g_usRsockBasePort = rsock_base_port();#if( CONFIG_BOARD_GMPU == TRUE ) g_ulRsGateWay[0] = 0; g_ulRsGateWay[1] = 0; if( DB_SUCC != db_get_sys_pub_param_value(PARAM_SYS_FE0_GAGEWAY_IP, szIpStr) ) { db_update_sys_pub_param_value( PARAM_SYS_FE0_GAGEWAY_IP, "FE0 gateway ip address", "0.0.0.0" ); } else { if( 0 == aos_strtoipaddr(szIpStr, &ulIpAddr) ) { g_ulRsGateWay[0] = AOS_HTONL(ulIpAddr); } } if( DB_SUCC != db_get_sys_pub_param_value(PARAM_SYS_FE1_GATEWAY_IP, szIpStr) ) { db_update_sys_pub_param_value( PARAM_SYS_FE1_GATEWAY_IP, "FE1 gateway ip address", "0.0.0.0" ); } else { if( 0 == aos_strtoipaddr(szIpStr, &ulIpAddr) ) { g_ulRsGateWay[1] = AOS_HTONL(ulIpAddr); } }#endif g_pRsockInitFlag = 1; break; case STARTUP_GO: aos_timer_start( NULL, MPE_RSOCK, 5000, RSOCK_FREE_PORT_TIMER, 0, AOS_TIMER_LOOP ); break; default: break; } return AOS_SUCC;}VOID rsock_msg_proc( MSG_S *msg, VOID*pvMsgBuf ){ RSOCK s; AOS_ASSERT( NULL != msg && NULL != pvMsgBuf ); if( NULL == msg || NULL == pvMsgBuf ) { return; } if( MPE_RSOCK != msg->dstMpe || LOCAL_PROCESSOR_ID != msg->dstProcessorId ) { return; } switch( msg->srcMpe ) { case MPE_TIMER: rsock_timer( ((TIMER_MSG_S*)pvMsgBuf)->ulTimerName,((TIMER_MSG_S*)pvMsgBuf)->ulPara ); break; case MPE_RSOCK: s = (RSOCK)*(U32*)pvMsgBuf; rsock_close(s); break; case MPE_DEBUG: rsock_debug_proc( ((DEBUG_MSG_S*)pvMsgBuf)->ulCmd, ((DEBUG_MSG_S*)pvMsgBuf)->ulPara1 ); break; default: break; }}U16 rsock_base_port(){ U16 usP2pListenPort[P2P_LISTEN_PORT_NUM]; p2p_get_local_port(usP2pListenPort); if( usP2pListenPort[0] > 20000 && usP2pListenPort[0] < (65535-RSOCK_FREE_PORT_NUM) ) { return usP2pListenPort[0]; } return RSOCK_FREE_PORT_BASE;}VOID rsock_timer( U32 name, U32 para ){ SOCKADDRIN_S addr; RSOCK s; U32 N; if( RSOCK_FREE_PORT_TIMER == name ) { rsock_port_expire(); return; } s = para & 0xffff; N = para >> 16; if( s >= MAX_RSOCK_NUM || !g_pstRsock[s].init ) { AOS_ASSERT(0); return; } switch( name ) { case RSOCK_SYN_SEND_TIMER: if( RSOCK_STATE_SYN_SEND == g_pstRsock[s].tcp_state ) { addr.sin_stAddr.s_ulAddr = g_pstRsock[s].peer_ip; addr.sin_usPort = AOS_HTONS(g_pstRsock[s].peer_port); #if( CONFIG_BOARD_GMPU == TRUE ) lcm_send_tcp_signal_by_if( g_pstRsock[s].if_index, LCM_TCP_SYN, g_pstRsock[s].lcl_port, g_pstRsock[s].tcp_seq, g_pstRsock[s].tcp_ack, &addr ); #else lcm_send_tcp_signal_to_eth( LCM_TCP_SYN, g_pstRsock[s].lcl_port, g_pstRsock[s].tcp_seq, g_pstRsock[s].tcp_ack, &addr ); #endif N++; if( N > 10 ) { N = 1; } aos_timer_start( &g_pstRsock[s].tcp_tmr, MPE_RSOCK, N*RSOCK_SYN_SEND_TIMER_LEN, RSOCK_SYN_SEND_TIMER, s | ( N << 16 ), AOS_TIMER_NO_LOOP ); if( g_ulRsockDbgFlag ) { aos_printf( MPE_RSOCK, "RSOCK(%u): send syn to %A %u", s, g_pstRsock[s].peer_ip, g_pstRsock[s].peer_port ); } } break; case RSOCK_SYN_RECV_TIMER: if( 0 == g_pstRsock[s].ref ) { rsock_free(&g_pstRsock[s]); g_ulRsockProtectNum1++; } break; case RSOCK_WAIT_REF_TIMER: if( 0 == g_pstRsock[s].ref ) { rsock_free(&g_pstRsock[s]); g_ulRsockProtectNum2++; } break; default: break; }}VOID rsock_debug_proc( U32 cmd, U32 para ){ switch( cmd ) { case 1: aos_printf( MPE_RSOCK, "g_ulRsockDbgFlag=%u", g_ulRsockDbgFlag ); break; case 2: aos_printf( MPE_RSOCK, "set g_ulRsockDbgFlag from %u to %u", g_ulRsockDbgFlag, para ); g_ulRsockDbgFlag = para; break; case 10: aos_printf( MPE_RSOCK, "g_ulRsockDbgIpFilter=%A", g_ulRsockDbgIpFilter ); break; case 11: aos_printf( MPE_RSOCK, "set g_ulRsockDbgIpFilter from %A to %A", g_ulRsockDbgIpFilter, para ); g_ulRsockDbgIpFilter = para; break; case 12: aos_printf( MPE_RSOCK, "g_ulRsockIpRefreshShowFlag=%u", g_ulRsockIpRefreshShowFlag ); break; case 13: aos_printf( MPE_RSOCK, "set g_ulRsockIpRefreshShowFlag from %u to %u", g_ulRsockIpRefreshShowFlag, para ); g_ulRsockIpRefreshShowFlag = para; break; default: aos_printf( MPE_RSOCK, "cmd 100 1 to show g_ulRsockDbgFlag" ); aos_printf( MPE_RSOCK, "cmd 100 2 para to set g_ulRsockDbgFlag" ); aos_printf( MPE_RSOCK, "cmd 100 10 to show g_ulRsockDbgIpFilter" ); aos_printf( MPE_RSOCK, "cmd 100 11 para to set g_ulRsockDbgIpFilter" ); aos_printf( MPE_RSOCK, "cmd 100 12 to show g_ulRsockIpRefreshShowFlag" ); aos_printf( MPE_RSOCK, "cmd 100 13 para to set g_ulRsockIpRefreshShowFlag" ); break; }}RSOCK rsock_init( U32 proto, U32 ip, U16 port, U16 lcl_port, U32 if_index, U32 alloc_lclport_flag, U16*new_lclport ){ U32 k,allocated = 0; struct aos_list *list, *node; rsock_t *rs; U16 new_port;#if( CONFIG_BOARD_GMPU == TRUE ) alloc_lclport_flag = 0;#else if_index = 0; #endif if( !g_pRsockInitFlag ) { AOS_ASSERT(0); return NULL_RSOCK; }#if( TXRX_INTERUPPT_ENABLE == TRUE ) if( intCount() ) { AOS_ASSERT_FUNC( 0, aos_printf(0,"rsock init in interrupt,ip=%A,port=%u,proto=%u",ip,port,proto); aos_task_show_call_stack(0) ); }#endif k = RSOCK_HASHFUNC( port, ip ); if( RSOCK_PROTO_UDP == proto ) { list = &g_RsockHashList4Udp[k]; } else if( RSOCK_PROTO_TCP == proto ) { list = &g_RsockHashList4Tcp[k]; } else { AOS_ASSERT(0); return NULL_RSOCK; } for( node = list->next; node != list; node = node->next ) { rs = aos_list_entry( node, rsock_t, rsock_next ); if( rs->peer_ip == ip && rs->peer_port == port &&( alloc_lclport_flag || rs->lcl_port == lcl_port ) #if( CONFIG_BOARD_GMPU == TRUE ) && rs->if_index == if_index#endif ) { if( RSOCK_PROTO_TCP == proto && 0 == rs->ref && RSOCK_STATE_ESTABLISHED == rs->tcp_state ) { if( NULL != rs->tcp_tmr ) { aos_timer_stop(&rs->tcp_tmr); } } rs->ref++; if( NULL != new_lclport ) { *new_lclport = rs->lcl_port; } if( g_ulRsockDbgIpFilter == ip ) { aos_printf( 0, "rsock init:SOCK=%d,REF=%u,ip=%A,port=%u,lclport=%u,allocflag=%u,proto=%u", (rs - g_pstRsock),rs->ref,ip, port,lcl_port,alloc_lclport_flag,proto ); } return rs - g_pstRsock; } } new_port = lcl_port; if( alloc_lclport_flag ) { if( RSOCK_PROTO_UDP == proto ) { new_port = rsock_alloc_udp_port(); } else { new_port = rsock_alloc_tcp_port(); } if( U16_BUTT != new_port ) { allocated = 1; lcl_port = new_port; } else { if( RSOCK_PROTO_UDP == proto ) { AOS_ASSERT(0); } else { AOS_ASSERT(0); } if( g_ulRsockDbgFlag ) { aos_printf( MPE_RSOCK, "rsock_init:alloc port fail,proto=%u,peerip=%A,peerport=%u", proto,ip,port ); } } } if( NULL != new_lclport ) { *new_lclport = lcl_port; } node = aos_list_fetch(&g_FreeRsockList); if( NULL != node ) { rs = aos_list_entry( node, rsock_t, rsock_next ); rs->init = 1; rs->ref = 1; rs->proto = (U8)proto; rs->is_tcp_server = 0; rs->alloc_flag = (U8)allocated; rs->connected = ((RSOCK_PROTO_UDP == proto) ? 1 : 0); rs->tcp_state = RSOCK_STATE_INIT; rs->seq_init = 0; rs->peer_ip = ip;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -