// SoftEther VPN Source Code - Developer Edition Master Branch // Mayaqua Kernel // Network.h // Header of Network.c #ifndef NETWORK_H #define NETWORK_H #include "Encrypt.h" #include "Mayaqua.h" #include // This is needed only for the SSL/TLS version defines #ifdef OS_UNIX #include #ifdef UNIX_LINUX #include #endif #ifdef UNIX_OPENBSD #include #endif #endif // Dynamic Value struct DYN_VALUE { char Name[256]; // Name UINT64 Value; // Value }; #define DYN64(id, default_value) ( (UINT64)GetDynValueOrDefaultSafe ( #id , (UINT64)( default_value ))) #define DYN32(id, default_value) (UINT)DYN64(id, (UINT)default_value) #define MAX_HOST_NAME_LEN 255 // Maximum length of the host name #define TIMEOUT_INFINITE (0x7fffffff) #define TIMEOUT_TCP_PORT_CHECK (10 * 1000) #define TIMEOUT_SSL_CONNECT (15 * 1000) #define TIMEOUT_NETBIOS_HOSTNAME (100) #define SOCKET_BUFFER_SIZE 0x10000000 #define UDPLISTENER_CHECK_INTERVAL 1000ULL #define UDPLISTENER_WAIT_INTERVAL 1234 #define UDP_MAX_MSG_SIZE_DEFAULT 65507 #define MAX_NUM_IGNORE_ERRORS 1024 #define DEFAULT_CIPHER_LIST "ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:ECDHE+AES256:DHE+AES256:RSA+AES" // SSL logging function //#define ENABLE_SSL_LOGGING #define SSL_LOGGING_DIRNAME "@ssl_log" // Private IP list file #define PRIVATE_IP_TXT_FILENAME "$private_ip.txt" // Start range of the random UDP port #define RAND_UDP_PORT_START 5000 #define RAND_UDP_PORT_END 65530 #define RAND_UDP_PORT_DEFAULT_NUM_RETRY 64 // Special Port #define MAKE_SPECIAL_PORT(p) (UINT)((UINT)0x10000 | (UINT)(p)) #define IS_SPECIAL_PORT(p) (MAKEBOOL((p) & (UINT)0x10000)) #define GET_SPECIAL_PORT(p) (UINT)((UINT)(p) & (UINT)0xffff) // Random R-UDP port ID #define RAND_PORT_ID_SERVER_LISTEN 1 // UDP buffer size #define UDP_MAX_BUFFER_SIZE 11911168 // Expiration of the cache acquired from the IP address list of the host #define HOST_IP_ADDRESS_LIST_CACHE (5 * 1000) // IP address struct IP { BYTE address[16]; // IP address (RFC 3493 format used for IPv4) UINT ipv6_scope_id; // IPv6 scope ID }; // Pointer to the beginning of the IPv4 address #define IPV4(address) (&address[12]) #define IPV4_SIZE (4) #define CmpIpAddr(ip1, ip2) (Cmp((ip1)->address, (ip2)->address, sizeof((ip1)->address))) #define IsIP6(ip) (ip && IsIP4(ip) == false) #define IsZeroIp(ip) (IsZeroIP(ip)) // IPv6 address (different format) struct IPV6_ADDR { UCHAR Value[16]; // Value } GCC_PACKED; // IPv6 Address Types #define IPV6_ADDR_UNICAST 1 // Unicast #define IPV6_ADDR_LOCAL_UNICAST 2 // Local unicast #define IPV6_ADDR_GLOBAL_UNICAST 4 // Global Unicast #define IPV6_ADDR_MULTICAST 8 // Multicast #define IPV6_ADDR_ALL_NODE_MULTICAST 16 // All-nodes multicast #define IPV6_ADDR_ALL_ROUTER_MULTICAST 32 // All routers multicast #define IPV6_ADDR_SOLICIATION_MULTICAST 64 // Solicited-node multicast #define IPV6_ADDR_ZERO 128 // All zeros #define IPV6_ADDR_LOOPBACK 256 // Loop-back // Client list struct IP_CLIENT { IP IpAddress; // IP address UINT NumConnections; // The number of connections }; // Socket event struct SOCK_EVENT { REF *ref; // Reference counter #ifdef OS_WIN32 void *hEvent; // Pointer to a Win32 event handle #else // OS_WIN32 LIST *SockList; // Socket list int pipe_read, pipe_write; // Pipe UINT current_pipe_data; // Amount of data in the current pipe #endif // OS_WIN32 }; // Type of socket #define SOCK_TCP 1 #define SOCK_UDP 2 #define SOCK_INPROC 3 #define SOCK_RUDP_LISTEN 5 #define SOCK_REVERSE_LISTEN 6 // SSL Accept Settings struct SSL_ACCEPT_SETTINGS { bool Tls_Disable1_0; bool Tls_Disable1_1; bool Tls_Disable1_2; bool Tls_Disable1_3; bool Override_Security_Level; UINT Override_Security_Level_Value; }; // Socket struct SOCK { REF *ref; // Reference counter LOCK *lock; // Lock LOCK *ssl_lock; // Lock related to the SSL LOCK *disconnect_lock; // Disconnection lock SOCKET socket; // Socket number SSL *ssl; // SSL object struct ssl_ctx_st *ssl_ctx; // SSL_CTX char SniHostname[256]; // SNI host name UINT Type; // Type of socket bool Connected; // Connecting flag bool ServerMode; // Server mode bool AsyncMode; // Asynchronous mode bool SecureMode; // SSL communication mode bool ListenMode; // In listening BUF *SendBuf; // Transmission buffer bool IpClientAdded; // Whether it has been added to the list IP_CLIENT bool LocalOnly; // Only local bool EnableConditionalAccept; // Conditional Accept is Enabled IP RemoteIP; // IP address of the remote host IP LocalIP; // IP address of the local host char *RemoteHostname; // Remote host name UINT RemotePort; // Port number of the remote side UINT LocalPort; // Port number of the local side UINT64 SendSize; // Total size of the sent data UINT64 RecvSize; // Total size of received data UINT64 SendNum; // Number of sent data blocks UINT64 RecvNum; // Number of received data blocks X *RemoteX; // Certificate of the remote host X *LocalX; // Certificate of the local host char *CipherName; // Cipher algorithm name char *WaitToUseCipher; // Set the algorithm name to want to use bool IgnoreRecvErr; // Whether the RecvFrom error is ignorable bool IgnoreSendErr; // Whether the SendTo error is ignorable UINT TimeOut; // Time-out value SOCK_EVENT *SockEvent; // Associated socket-event bool CancelAccept; // Cancel flag of the Accept bool AcceptCanceled; // Flag which shows canceling of the Accept bool WriteBlocked; // Previous write is blocked bool NoNeedToRead; // Is not required to read bool Disconnecting; // Disconnecting bool UdpBroadcast; // UDP broadcast mode void *Param; // Any parameters bool IPv6; // IPv6 bool IsRawSocket; // Whether it is a raw socket const char *SslVersion; // SSL version UINT RawSocketIPProtocol; // IP protocol number if it's a raw socket TUBE *SendTube; // Tube for transmission TUBE *RecvTube; // Tube for reception QUEUE *InProcAcceptQueue; // Accept queue of the in-process socket EVENT *InProcAcceptEvent; // Accept event of the in-process socket FIFO *InProcRecvFifo; // Receive FIFO of the in-process socket UINT UdpMaxMsgSize; // Maximum transmitting and receiving size at a time on UDP int CurrentTos; // Current ToS value bool IsTtlSupported; // Whether the TTL value is supported UINT CurrentTtl; // Current TTL value RUDP_STACK *R_UDP_Stack; // R-UDP stack char UnderlayProtocol[64]; // Underlying protocol char ProtocolDetails[256]; // Protocol details QUEUE *ReverseAcceptQueue; // Accept queue for the reverse socket EVENT *ReverseAcceptEvent; // Accept event for the reverse socket bool IsReverseAcceptedSocket; // Whether it is a reverse socket IP Reverse_MyServerGlobalIp; // Self global IP address when using the reverse socket UINT Reverse_MyServerPort; // Self port number when using the reverse socket UCHAR Ssl_Init_Async_SendAlert[2]; // Initial state of SSL send_alert SSL_ACCEPT_SETTINGS SslAcceptSettings; // SSL Accept Settings bool RawIP_HeaderIncludeFlag; #ifdef ENABLE_SSL_LOGGING // SSL Logging (for debug) bool IsSslLoggingEnabled; // Flag IO *SslLogging_Recv; // for Recv IO *SslLogging_Send; // for Send LOCK *SslLogging_Lock; // Locking #endif // ENABLE_SSL_LOGGING void *hAcceptEvent; // Event for Accept // R-UDP socket related bool IsRUDPSocket; // Whether this is R-UDP socket TUBE *BulkSendTube; // Tube for Bulk send TUBE *BulkRecvTube; // Tube for Bulk receive SHARED_BUFFER *BulkSendKey; // Bulk send key SHARED_BUFFER *BulkRecvKey; // Bulk receive key UINT RUDP_OptimizedMss; // Optimal MSS value #ifdef OS_UNIX pthread_t CallingThread; // Thread that is calling the system call #endif // OS_UNIX #ifdef OS_WIN32 void *hEvent; // Event for asynchronous mode #endif // OS_WIN32 }; // Underlying protocol description string of socket #define SOCK_UNDERLAY_NATIVE_V6 "Standard TCP/IP (IPv6)" #define SOCK_UNDERLAY_NATIVE_V4 "Standard TCP/IP (IPv4)" #define SOCK_UNDERLAY_NAT_T "VPN over UDP with NAT-T (IPv4)" #define SOCK_UNDERLAY_DNS "VPN over DNS (IPv4)" #define SOCK_UNDERLAY_ICMP "VPN over ICMP (IPv4)" #define SOCK_UNDERLAY_INPROC "In-Process Pipe" #define SOCK_UNDERLAY_INPROC_EX "Legacy VPN - %s" #define SOCK_UNDERLAY_AZURE "TCP/IP via VPN Azure (IPv4)" // Constant of the return value #define SOCK_LATER (0xffffffff) // In blocking // Socket Set #define MAX_SOCKSET_NUM 60 // Number of sockets that can be stored in a socket set struct SOCKSET { UINT NumSocket; // The number of sockets SOCK *Sock[MAX_SOCKSET_NUM]; // Array of pointers to the socket }; // Cancel object struct CANCEL { REF *ref; // Reference counter bool SpecialFlag; // Special flag (associated to the event which is generated by Win32 driver) #ifdef OS_WIN32 void *hEvent; // Pointer to a Win32 event handle #else // OS_WIN32 int pipe_read, pipe_write; // Pipe int pipe_special_read2, pipe_special_read3; #endif // OS_WIN32 }; // Routing table entry struct ROUTE_ENTRY { IP DestIP; IP DestMask; IP GatewayIP; bool LocalRouting; bool PPPConnection; UINT Metric; UINT IfMetric; UINT InterfaceID; UINT64 InnerScore; bool Active; }; // Routing table struct ROUTE_TABLE { UINT NumEntry; UINT HashedValue; ROUTE_ENTRY **Entry; }; // ICMP response result struct ICMP_RESULT { bool Ok; // Whether a correct response returned bool Timeout; // Whether a time-out is occurred UCHAR Type; // Message type UCHAR Code; // Message code UCHAR Ttl; // TTL UCHAR *Data; // Data body UINT DataSize; // Data size UINT Rtt; // Round Trip Time IP IpAddress; // IP address }; // NETBIOS name requests typedef struct NBTREQUEST { USHORT TransactionId; USHORT Flags; USHORT NumQuestions; USHORT AnswerRRs; USHORT AuthorityRRs; USHORT AdditionalRRs; UCHAR Query[38]; } NBTREQUEST; // NETBIOS name response typedef struct NBTRESPONSE { USHORT TransactionId; USHORT Flags; USHORT NumQuestions; USHORT AnswerRRs; USHORT AuthorityRRs; USHORT AdditionalRRs; UCHAR Response[61]; } NBTRESPONSE; // Socket list typedef struct SOCKLIST { LIST *SockList; } SOCKLIST; // Parameters for timeout thread for Solaris typedef struct SOCKET_TIMEOUT_PARAM { SOCK *sock; CANCEL *cancel; THREAD *thread; bool unblocked; } SOCKET_TIMEOUT_PARAM; // Parameters for the IP address release thread struct WIN32_RELEASEADDRESS_THREAD_PARAM { REF *Ref; char Guid[MAX_SIZE]; UINT Timeout; bool Ok; bool Renew; }; // TCP table entry typedef struct TCPTABLE { UINT Status; IP LocalIP; UINT LocalPort; IP RemoteIP; UINT RemotePort; UINT ProcessId; } TCPTABLE; // State of TCP #define TCP_STATE_CLOSED 1 #define TCP_STATE_LISTEN 2 #define TCP_STATE_SYN_SENT 3 #define TCP_STATE_SYN_RCVD 4 #define TCP_STATE_ESTAB 5 #define TCP_STATE_FIN_WAIT1 6 #define TCP_STATE_FIN_WAIT2 7 #define TCP_STATE_CLOSE_WAIT 8 #define TCP_STATE_CLOSING 9 #define TCP_STATE_LAST_ACK 10 #define TCP_STATE_TIME_WAIT 11 #define TCP_STATE_DELETE_TCB 12 // Routing table changing notification struct ROUTE_CHANGE { ROUTE_CHANGE_DATA *Data; }; // Tube flush list struct TUBE_FLUSH_LIST { LIST *List; // List }; // Tube struct TUBE { REF *Ref; // Reference counter LOCK *Lock; // Lock QUEUE *Queue; // Packet queue EVENT *Event; // Event SOCK_EVENT *SockEvent; // SockEvent UINT SizeOfHeader; // Header size TUBEPAIR_DATA *TubePairData; // Tube pair data UINT IndexInTubePair; // Number in the tube pair bool IsInFlushList; // Whether it is registered in the Tube Flush List void *Param1, *Param2, *Param3; UINT IntParam1, IntParam2, IntParam3; UINT64 DataTimeout; }; // Data that is to send and to receive in the tube struct TUBEDATA { void *Data; // Body of data UINT DataSize; // The size of the data void *Header; // The body of the header UINT HeaderSize; // Size of the header }; // Tube pair data struct TUBEPAIR_DATA { bool IsDisconnected; // Disconnection flag REF *Ref; // Reference counter LOCK *Lock; // Lock EVENT *Event1, *Event2; // Event SOCK_EVENT *SockEvent1, *SockEvent2; // SockEvent }; // TCP raw data struct TCP_RAW_DATA { IP SrcIP; // Source IP address IP DstIP; // Destination IP address UINT SrcPort; // Source port UINT DstPort; // Destination port FIFO *Data; // Data body }; // UDP listener socket entry struct UDPLISTENER_SOCK { IP IpAddress; // IP address UINT Port; // Port number SOCK *Sock; // Socket bool HasError; // Whether an error occurs bool Mark; // Mark bool ErrorDebugDisplayed; // Whether the error has been displayed UINT64 NextMyIpAndPortPollTick; // Time to check the self IP address and port number next IP PublicIpAddress; // Global IP address UINT PublicPort; // Global port number }; // UDP packet struct UDPPACKET { IP SrcIP; // Source IP address IP DstIP; // Destination IP address UINT SrcPort; // Source port UINT DestPort; // Destination port UINT Size; // Data size void *Data; // Data body UINT Type; // Type }; // UDP listener packet receipt notification procedure typedef void (UDPLISTENER_RECV_PROC)(UDPLISTENER *u, LIST *packet_list); // UDP listener struct UDPLISTENER { bool Halt; // Halting flag SOCK_EVENT *Event; // Event THREAD *Thread; // Thread LIST *PortList; // Port list LIST *SockList; // Socket list UINT64 LastCheckTick; // Time which the socket list was checked last UDPLISTENER_RECV_PROC *RecvProc; // Receive procedure LIST *SendPacketList; // Transmission packet list UINT PacketType; // The type to set when creating an UDPPACKET void *Param; // Parameters INTERRUPT_MANAGER *Interrupts; // Interrupt manager bool HostIPAddressListChanged; // IP address list of the host has changed bool IsEspRawPortOpened; // Whether the raw port opens bool PollMyIpAndPort; // Examine whether the global IP and the port number of its own QUERYIPTHREAD *GetNatTIpThread; // NAT-T IP address acquisition thread IP ListenIP; // Listen IP }; #define QUERYIPTHREAD_INTERVAL_LAST_OK (3 * 60 * 60 * 1000) #define QUERYIPTHREAD_INTERVAL_LAST_NG (30 * 1000) // IP address acquisition thread struct QUERYIPTHREAD { THREAD *Thread; // Thread EVENT *HaltEvent; // Halting event bool Halt; // Halting flag LOCK *Lock; // Lock IP Ip; // Get the IP address char Hostname[MAX_SIZE]; // Host name UINT IntervalLastOk; // Interval if last was OK UINT IntervalLastNg; // Interval if last was NG }; // Interrupt management struct INTERRUPT_MANAGER { LIST *TickList; // Time list }; // SSL BIO struct SSL_BIO { BIO *bio; // BIO FIFO *SendFifo; // Transmission FIFO FIFO *RecvFifo; // Reception FIFO bool IsDisconnected; // Disconnected bool NoFree; // Not to release the BIO }; // SSL pipe struct SSL_PIPE { bool ServerMode; // Whether it's in the server mode bool IsDisconnected; // Disconnected int SslVersion; SSL *ssl; // SSL object struct ssl_ctx_st *ssl_ctx; // SSL_CTX SSL_BIO *SslInOut; // I/O BIO for the data in the SSL tunnel SSL_BIO *RawIn, *RawOut; // Input and output BIO of the data flowing through the physical network }; // IP address block list struct IPBLOCK { IP Ip; // IP address IP Mask; // Subnet mask }; // R-UDP related constants #define RUDP_RESEND_TIMER 200 // Retransmission timer (initial value) #define RUDP_RESEND_TIMER_MAX 4792 // Retransmission timer (maximum value) #define RUDP_KEEPALIVE_INTERVAL_MIN 2500 // Transmission interval of Keep Alive (minimum) #define RUDP_KEEPALIVE_INTERVAL_MAX 4792 // Transmission interval of Keep Alive (maximum) #define RUDP_TIMEOUT 12000 // Time-out of R-UDP communication #define RUDP_DIRECT_CONNECT_TIMEOUT 5000 // R-UDP direct connection time-out #define RUDP_MAX_SEGMENT_SIZE 512 // Maximum segment size #define RUDP_BULK_KEY_SIZE_MAX 128 // Bulk key size Max #define RUDP_BULK_KEY_SIZE_V2 32 // V2: Bulk key size #define RUDP_BULK_IV_SIZE_V2 12 // V2: Bulk IV size #define RUDP_BULK_MAC_SIZE_V2 16 // V2: Bulk MAC size // Maximum R-UDP packet size #define RUDP_MAX_PACKET_SIZE (RUDP_MAX_SEGMENT_SIZE + sizeof(UINT64) * RUDP_MAX_NUM_ACK + SHA1_SIZE * 2 + sizeof(UINT64) * 4 + sizeof(UINT) + 255) #define RUDP_MAX_NUM_ACK 64 // Maximum number of ACKs #define RUDP_LOOP_WAIT_INTERVAL_S 1234 // Waiting time in the thread main loop (in server side) #define RUDP_LOOP_WAIT_INTERVAL_C 100 // Waiting time in the thread main loop (in client side) #define RUDP_MAX_FIFO_SIZE (1600 * 1600) // The maximum FIFO buffer size // Interval for sending ICMP Echo from the client side when R-UDP used in ICMP mode #define RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MIN 1000 #define RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MAX 3000 // R-UDP error code #define RUDP_ERROR_OK 0 // Success #define RUDP_ERROR_UNKNOWN 1 // Unknown Error #define RUDP_ERROR_TIMEOUT 2 // Time-out #define RUDP_ERROR_NAT_T_GETIP_FAILED 3 // IP address acquisition failure of NAT-T server #define RUDP_ERROR_NAT_T_NO_RESPONSE 4 // There is no response from the NAT-T server #define RUDP_ERROR_NAT_T_TWO_OR_MORE 5 // There are two or more hosts on the same destination IP address #define RUDP_ERROR_NAT_T_NOT_FOUND 6 // Host does not exist at the specified IP address #define RUDP_ERROR_USER_CANCELED 7 // Cancel by the user // R-UDP segment struct RUDP_SEGMENT { UINT64 SeqNo; // Sequence number UINT Size; // Size UCHAR Data[RUDP_MAX_SEGMENT_SIZE]; // Data UINT64 NextSendTick; // Next transmission time UINT NumSent; // Number of times sent }; // Status of R-UDP session #define RUDP_SESSION_STATUS_CONNECT_SENT 0 // Connection request sent #define RUDP_SESSION_STATUS_ESTABLISHED 1 // Connection established // Quota #define RUDP_QUOTA_MAX_NUM_SESSIONS_PER_IP DYN32(RUDP_QUOTA_MAX_NUM_SESSIONS_PER_IP, 1000) // The number of R-UDP sessions per an IP address #define RUDP_QUOTA_MAX_NUM_SESSIONS DYN32(RUDP_QUOTA_MAX_NUM_SESSIONS, 30000) // Limit of the Number of sessions // Range of the sequence numbers of bulk packet #define RUDP_BULK_SEQ_NO_RANGE 16384ULL #define RUDP_BULK_MAX_RECV_PKTS_IN_QUEUE 8192 // R-UDP session struct RUDP_SESSION { UINT Status; // Status bool ServerMode; // Whether it's in the server mode bool DisconnectFlag; // Disconnection flag bool DisconnectedByYou; // Disconnected from opponent bool UseHMac; IP MyIp; // IP address of itself UINT MyPort; // Port number of itself IP YourIp; // Opponent IP address UINT YourPort; // Opponent port number LIST *SendSegmentList; // Transmission segment list LIST *RecvSegmentList; // Received segments list LIST *ReplyAckList; // List of ACKs in response SOCK *TcpSock; // Corresponding TCP socket UINT64 LastSentTick; // Time which the data has been sent last UINT64 LastRecvTick; // Time which the data has been received last UCHAR Key_Init[SHA1_SIZE]; // Initial key UCHAR Key_Send[SHA1_SIZE]; // Key that is used to send UCHAR Key_Recv[SHA1_SIZE]; // Key that is used to receive UCHAR Magic_KeepAliveRequest[SHA1_SIZE]; // The magic number for the KeepAlive request UCHAR Magic_KeepAliveResponse[SHA1_SIZE]; // The magic number for KeepAlive response UINT64 Magic_Disconnect; // Disconnection Signal UINT64 NextSendSeqNo; // Transmission sequence number to be used next UINT64 LastRecvCompleteSeqNo; // Sequence number of receiving complete // (This indicates all segments which have sequence number up to this number are received completely) UCHAR NextIv[SHA1_SIZE]; // IV value to be used next UINT NextKeepAliveInterval; // Interval value of KeepAlive to be used next FIFO *RecvFifo; // Reception FIFO FIFO *SendFifo; // Transmission FIFO UINT64 YourTick; // The largest value among received Tick from the opponent UINT64 LatestRecvMyTick; // Value of the last tick among the received tick values UINT64 LatestRecvMyTick2; // Variable for confirming whether LatestRecvMyTick2 changes UINT CurrentRtt; // Current RTT value UINT Icmp_Type; // Number of Type to be used in the ICMP USHORT Dns_TranId; // Value of transaction ID used in DNS UINT64 Client_Icmp_NextSendEchoRequest; // Time to send the next Echo Request in the ICMP SHARED_BUFFER *BulkSendKey; // Bulk send key SHARED_BUFFER *BulkRecvKey; // Bulk receive key UCHAR BulkNextIv[SHA1_SIZE]; // Next IV to the bulk send UINT64 BulkNextSeqNo; // Next SEQ NO to the bulk send bool FlushBulkSendTube; // Flag to be Flush the bulk send Tube UINT64 BulkRecvSeqNoMax; // Highest sequence number received UCHAR BulkNextIv_V2[RUDP_BULK_IV_SIZE_V2]; // Next IV to the bulk send (version 2) }; // NAT Traversal Server Information #define UDP_NAT_T_SERVER_TAG "x%c.x%c.dev.servers.nat-traversal.softether-network.net." #define UDP_NAT_T_SERVER_TAG_ALT "x%c.x%c.dev.servers.nat-traversal.uxcom.jp." #define UDP_NAT_T_PORT 5004 // Related to processing to get the IP address of the NAT-T server #define UDP_NAT_T_GET_IP_INTERVAL DYN32(UDP_NAT_T_GET_IP_INTERVAL, (5 * 1000)) // IP address acquisition interval of NAT-T server (before success) #define UDP_NAT_T_GET_IP_INTERVAL_MAX DYN32(UDP_NAT_T_GET_IP_INTERVAL, (150 * 1000)) // IP address acquisition interval of NAT-T server (before success) #define UDP_NAT_T_GET_IP_INTERVAL_AFTER DYN32(UDP_NAT_T_GET_IP_INTERVAL_AFTER, (5 * 60 * 1000)) // IP address acquisition interval of NAT-T server (after success) // Related to process to get the private IP address of itself with making a TCP connection to the NAT-T server #define UDP_NAT_T_GET_PRIVATE_IP_TCP_SERVER "www.msftncsi.com." #define UDP_NAT_T_PORT_FOR_TCP_1 80 #define UDP_NAT_T_PORT_FOR_TCP_2 443 #define UDP_NAT_TRAVERSAL_VERSION 1 #define UDP_NAT_T_GET_PRIVATE_IP_INTERVAL DYN32(UDP_NAT_T_GET_PRIVATE_IP_INTERVAL, (15 * 60 * 1000)) // Polling interval (before success) #define UDP_NAT_T_GET_PRIVATE_IP_INTERVAL_AFTER_MIN DYN32(UDP_NAT_T_GET_PRIVATE_IP_INTERVAL_AFTER_MIN, (30 * 60 * 1000)) // Polling interval (after success) #define UDP_NAT_T_GET_PRIVATE_IP_INTERVAL_AFTER_MAX DYN32(UDP_NAT_T_GET_PRIVATE_IP_INTERVAL_AFTER_MAX, (60 * 60 * 1000)) // Polling interval (after success) #define UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT DYN32(UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT, (5 * 1000)) // TCP connection time-out // About token acquisition from the NAT-T server #define UDP_NAT_T_GET_TOKEN_INTERVAL_1 DYN32(UDP_NAT_T_GET_TOKEN_INTERVAL_1, (5 * 1000)) // Token acquisition interval from the NAT-T server (If not acquired) #define UDP_NAT_T_GET_TOKEN_INTERVAL_FAIL_MAX DYN32(UDP_NAT_T_GET_TOKEN_INTERVAL_FAIL_MAX, 20) #define UDP_NAT_T_GET_TOKEN_INTERVAL_2_MIN DYN32(UDP_NAT_T_GET_TOKEN_INTERVAL_2_MIN, (20 * 60 * 1000)) // Token acquisition interval minimum value from the NAT-T server (If token have been obtained) #define UDP_NAT_T_GET_TOKEN_INTERVAL_2_MAX DYN32(UDP_NAT_T_GET_TOKEN_INTERVAL_2_MAX, (30 * 60 * 1000)) // Token acquisition interval maximum value from the NAT-T server (If token have been obtained) // The Register interval for NAT-T server #define UDP_NAT_T_REGISTER_INTERVAL_INITIAL DYN32(UDP_NAT_T_REGISTER_INTERVAL_INITIAL, (5 * 1000)) // Transmission interval when the Register is not completed #define UDP_NAT_T_REGISTER_INTERVAL_FAIL_MAX DYN32(UDP_NAT_T_REGISTER_INTERVAL_FAIL_MAX, 20) #define UDP_NAT_T_REGISTER_INTERVAL_MIN DYN32(UDP_NAT_T_REGISTER_INTERVAL_MIN, (220 * 1000)) // Minimum value of the Register interval #define UDP_NAT_T_REGISTER_INTERVAL_MAX DYN32(UDP_NAT_T_REGISTER_INTERVAL_MAX, (240 * 1000)) // Maximum value of the Register interval // Interval for checking whether the port number or the IP address is changed #define UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MIN DYN32(UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MIN, (24 * 1000)) #define UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MAX DYN32(UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MAX, (28 * 1000)) // The Connect Request interval for NAT-T server #define UDP_NAT_T_CONNECT_INTERVAL DYN32(UDP_NAT_T_CONNECT_INTERVAL, 200) // Polling interval for its own IP information acquisition to the NAT-T server in regular communication between the client and the server #define UDP_NAT_T_INTERVAL_MIN DYN32(UDP_NAT_T_INTERVAL_MIN, (5 * 60 * 1000)) #define UDP_NAT_T_INTERVAL_MAX DYN32(UDP_NAT_T_INTERVAL_MAX, (10 * 60 * 1000)) #define UDP_NAT_T_INTERVAL_INITIAL DYN32(UDP_NAT_T_INTERVAL_INITIAL, (3 * 1000)) #define UDP_NAT_T_INTERVAL_FAIL_MAX DYN32(UDP_NAT_T_INTERVAL_FAIL_MAX, 60) // R-UDP stack callback function definition typedef void (RUDP_STACK_INTERRUPTS_PROC)(RUDP_STACK *r); typedef bool (RUDP_STACK_RPC_RECV_PROC)(RUDP_STACK *r, UDPPACKET *p); // ICMP protocol number #define IP_PROTO_ICMPV4 0x01 // ICMPv4 protocol #define IP_PROTO_ICMPV6 0x3a // ICMPv6 protocol // R-UDP protocol #define RUDP_PROTOCOL_UDP 0 // UDP #define RUDP_PROTOCOL_ICMP 1 // ICMP #define RUDP_PROTOCOL_DNS 2 // DNS // Maximum time of continuously changing of the NAT-T hostname #define RUDP_NATT_MAX_CONT_CHANGE_HOSTNAME 30 #define RUDP_NATT_CONT_CHANGE_HOSTNAME_RESET_INTERVAL (5 * 60 * 1000) // Minimum time to wait for a trial to connect by ICMP and DNS in case failing to connect by TCP #define SOCK_CONNECT_WAIT_FOR_ICMP_AND_DNS_AT_LEAST 5000 #define RUDP_MAX_VALIDATED_SOURCE_IP_ADDRESSES 512 #define RUDP_VALIDATED_SOURCE_IP_ADDRESS_EXPIRES (RUDP_TIMEOUT * 2) // Validated Source IP Addresses for R-UDP struct RUDP_SOURCE_IP { UINT64 ExpiresTick; // Expires IP ClientIP; // Client IP address }; // R-UDP stack struct RUDP_STACK { bool ServerMode; // Whether it's in the server mode char SvcName[MAX_SIZE]; // Service name UCHAR SvcNameHash[SHA1_SIZE]; // Hash of the service name bool Halt; // Halting flag void *Param; // Parameters that can be used by developers UINT64 Now; // Current time EVENT *HaltEvent; // Halting event INTERRUPT_MANAGER *Interrupt; // Interrupt manager LIST *SessionList; // Session List SOCK *UdpSock; // UDP socket UINT Port; // Port number UINT Protocol; // Protocol SOCK_EVENT *SockEvent; // Socket event THREAD *Thread; // Thread LOCK *Lock; // Lock RUDP_STACK_INTERRUPTS_PROC *ProcInterrupts; // Interrupt notification callback RUDP_STACK_RPC_RECV_PROC *ProcRpcRecv; // RPC reception notification callback THREAD *IpQueryThread; // NAT-T server IP inquiry thread UCHAR TmpBuf[65536]; // Temporary buffer LIST *SendPacketList; // Transmission UDP packet list EVENT *NewSockConnectEvent; // Event to inform that a new socket is connected QUEUE *NewSockQueue; // Queue of new socket UINT64 TotalPhysicalReceived; // Physical amount of data received UINT64 TotalLogicalReceived; // Logical amount of data received UINT64 TotalPhysicalSent; // Physical amount of data transmitted UINT64 TotalLogicalSent; // Logical amount of data transmitted char CurrentRegisterHostname[MAX_SIZE]; // The host name of the the current destination of registration UINT NumChangedHostname; // How number of changing NAT-T hostname has occured continuously UINT64 NumChangedHostnameValueResetTick; // NAT-T server related bool NoNatTRegister; // Flag not to register with the NAT-T server UINT64 NatT_TranId; // Transaction ID is used to communicate with the NAT-T server UINT64 NatT_SessionKey; // Current Session Key IP NatT_IP; // IP address of the NAT-T server IP NatT_IP_Safe; // IP address of the NAT-T server (thread-safe) IP My_Private_IP; // Private IP address of itself IP My_Private_IP_Safe; // Private IP address of itself (thread-safe) UINT64 NatT_GetTokenNextTick; // Time to get the next token UINT NatT_GetTokenFailNum; // Token acquisition failure times char NatT_Token[MAX_SIZE]; // Token needed to communicate with NAT-T Server bool NatT_Token_Ok; // Flag of whether it have a valid token UINT64 NatT_RegisterNextTick; // Time to register next UINT NatT_RegisterFailNum; // The number of Register failures bool NatT_Register_Ok; // Is a successful registration char NatT_Registered_IPAndPort[128]; // IP address and port number at the time of registration success UINT64 NatT_NextNatStatusCheckTick; // Time to check the NAT state next UINT LastDDnsFqdnHash; // DNS FQDN hash value when last checked volatile UINT *NatTGlobalUdpPort; // NAT-T global UDP port UCHAR RandPortId; // Random UDP port ID bool NatT_EnableSourceIpValidation; // Enable the source IP address validation mechanism LIST *NatT_SourceIpList; // Authenticated source IP address list // For Client bool TargetIpAndPortInited; // The target IP address and the port number are initialized IP TargetIp; // Target IP address UINT TargetPort; // Target port number EVENT *TargetConnectedEvent; // Event to be set when the connection to the target is successful SOCK *TargetConnectedSock; // Connected socket bool ClientInitiated; // Flag to indicate that the connection is initiated bool DoNotSetTargetConnectedSock; // Flag indicating that it should not set the TargetConnectedSock USHORT Client_IcmpId, Client_IcmpSeqNo; // Sequence number and ICMP ID that is randomly generated on the client side }; // Data for the thread for serial connection attempts to a list of addresses struct CONNECT_SERIAL_PARAM { LIST *IpList; UINT Port; UINT Timeout; char Hostname[MAX_SIZE]; char HintStr[MAX_SIZE]; bool No_Get_Hostname; bool *CancelFlag; bool *NoDelayFlag; UINT *NatT_ErrorCode; char NatT_SvcName[MAX_SIZE]; SOCK *Sock; bool Finished; bool Ok; UINT64 FinishedTick; EVENT *FinishEvent; UINT Delay; UINT RetryDelay; bool Tcp_TryStartSsl; SSL_VERIFY_OPTION *SslOption; UINT *SslErr; bool Use_NatT; bool Force_NatT; IP *Ret_Ip; }; // Data for the thread for concurrent connection attempts for the R-UDP and TCP struct CONNECT_TCP_RUDP_PARAM { IP Ip; UINT Port; UINT Timeout; char Hostname[MAX_SIZE]; bool *CancelFlag; UINT NatT_ErrorCode; char SvcName[MAX_SIZE]; char HintStr[MAX_SIZE]; char TargetHostname[MAX_SIZE]; SOCK *Result_Nat_T_Sock; SOCK *Result_Tcp_Sock; bool Finished; bool Ok; UINT64 FinishedTick; EVENT *FinishEvent; UINT RUdpProtocol; UINT Delay; bool Tcp_TryStartSsl; SSL_VERIFY_OPTION *SslOption; UINT *SslErr; LOCK *CancelLock; SOCK *CancelDisconnectSock; bool Tcp_InNegotiation; }; struct SSL_VERIFY_OPTION { bool VerifyPeer; // Whether to verify SSL peer bool PromptOnVerifyFail; // Prompt on verification failure (Windows) bool AddDefaultCA; // Use default trust store bool VerifyHostname; // Verify server hostname LIST *CaList; // Trusted CA list X *SavedCert; // Saved server certificate }; #define SSL_DEFAULT_CONNECT_TIMEOUT (15 * 1000) // SSL default timeout // Header for TCP Pair struct TCP_PAIR_HEADER { bool EnableHMac; }; // The constants for file query by using UDP #define UDP_FILE_QUERY_RETRY_INTERVAL 100 // Retry interval #define UDP_FILE_QUERY_DST_PORT 5004 // Destination UDP port number #define UDP_FILE_QUERY_MAGIC_NUMBER "{5E465695-7923-4CCD-9B51-44444BE1E758}" // Magic number #define UDP_FILE_QUERY_BFLETS_TXT_FILENAME "|BFletsUdpList.txt" // Text file name of the IPv6 node list // The constant for DNS proxy for the B FLETs #define BFLETS_DNS_PROXY_PORT 443 #define BFLETS_DNS_PROXY_PATH "/ddns/queryhost.aspx" #define BFLETS_DNS_PROXY_CERT_HASH "EFAC5FA0CDD14E0F864EED58A73C35D7E33B62F3" #define BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F 500 // Timeout when searching for the server by UDP #define BFLETS_DNS_PROXY_TIMEOUT_FOR_QUERY 3000 // Timeout for the response from the proxy DNS server // FLET'S Hikar-Next (East) DNS proxy host name #define FLETS_NGN_EAST_DNS_PROXY_HOSTNAME "senet.aoi.flets-east.jp" #define FLETS_NGN_WEST_DNS_PROXY_HOSTNAME "senet.p-ns.flets-west.jp" #define FLETS_NGN_DNS_QUERY_TIMEOUT 1000 // FLET'S Hikar-Next host name query timeout // Detection result of the type of FLET'S line #define FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE 1 // NTT East B-FLETs #define FLETS_DETECT_TYPE_EAST_NGN_PRIVATE 2 // Wrapping in network of NTT East NGN #define FLETS_DETECT_TYPE_WEST_NGN_PRIVATE 4 // Wrapping in network of NTT West NGN // NIC adapter entry struct NIC_ENTRY { char IfName[MAX_SIZE]; UCHAR MacAddress[6]; }; int GetCurrentTimezone(); bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UINT sni_size); void SetDhParam(DH_CTX *dh); bool IsUseAlternativeHostname(); #ifdef OS_WIN32 int GetCurrentTimezoneWin32(); #endif // OS_WIN32 bool SendPack(SOCK *s, PACK *p); PACK *RecvPack(SOCK *s); PACK *RecvPackWithHash(SOCK *s); bool SendPackWithHash(SOCK *s, PACK *p); UINT GetErrorFromPack(PACK *p); PACK *PackError(UINT error); void CreateDummyValue(PACK *p); char *RecvLine(SOCK *s, UINT max_size); bool GetIPViaDnsProxyForJapanFlets(IP *ip_ret, char *hostname, bool ipv6, UINT timeout, bool *cancel, char *dns_proxy_hostname); bool GetDnsProxyIPAddressForJapanBFlets(IP *ip_ret, UINT timeout, bool *cancel); BUF *QueryFileByUdpForJapanBFlets(UINT timeout, bool *cancel); BUF *QueryFileByIPv6Udp(LIST *ip_list, UINT timeout, bool *cancel); UINT DetectFletsType(); void ListenTcpForPopupFirewallDialog(); bool DetectIsServerSoftEtherVPN(SOCK *s); void ConnectThreadForTcp(THREAD *thread, void *param); void ConnectThreadForRUDP(THREAD *thread, void *param); void ConnectThreadForOverDnsOrIcmp(THREAD *thread, void *param); void ConnectThreadForIPv4(THREAD *thread, void *param); void ConnectThreadForIPv6(THREAD *thread, void *param); SOCK *CreateTCPSock(SOCKET s, bool is_ipv6, IP *current_ip, bool no_get_hostname, char *hostname_original); SOCK *NewRUDPClientNatT(char *svc_name, IP *ip, UINT *error_code, UINT timeout, bool *cancel, char *hint_str, char *target_hostname); RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode, volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip); SOCK *NewRUDPClientDirect(char *svc_name, IP *ip, UINT port, UINT *error_code, UINT timeout, bool *cancel, SOCK *sock, SOCK_EVENT *sock_event, UINT local_port, bool over_dns_mode); RUDP_STACK *NewRUDP(bool server_mode, char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, SOCK *sock, SOCK_EVENT *sock_event, bool server_no_natt_register, bool over_dns_mode, IP *client_target_ip, volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip); void FreeRUDP(RUDP_STACK *r); void RUDPMainThread(THREAD *thread, void *param); void RUDPRecvProc(RUDP_STACK *r, UDPPACKET *p); void RUDPInterruptProc(RUDP_STACK *r); void RUDPIpQueryThread(THREAD *thread, void *param); void RUDPSendPacket(RUDP_STACK *r, IP *dest_ip, UINT dest_port, void *data, UINT size, UINT icmp_type); void GetCurrentMachineIpProcessHash(void *hash); void GetCurrentMachineIpProcessHashInternal(void *hash); int RUDPCompareSessionList(void *p1, void *p2); RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your_ip, UINT your_port, UCHAR *init_key); void RUDPFreeSession(RUDP_SESSION *se); int RUDPCompareSegmentList(void *p1, void *p2); RUDP_SESSION *RUDPSearchSession(RUDP_STACK *r, IP *my_ip, UINT my_port, IP *your_ip, UINT your_port); void RUDPSendSegmentNow(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq_no, void *data, UINT size); void RUDPSendSegment(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT size); bool RUDPProcessRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size); bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size); void RUDPProcessAck(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq); void RUDPProcessAck2(RUDP_STACK *r, RUDP_SESSION *se, UINT64 max_seq); void RUDPProcessRecvPayload(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq, void *payload_data, UINT payload_size); void RUDPInitSock(RUDP_STACK *r, RUDP_SESSION *se); void RUDPDisconnectSession(RUDP_STACK *r, RUDP_SESSION *se, bool disconnected_by_you); UINT64 RUDPGetCurrentSendingMinSeqNo(RUDP_SESSION *se); UINT64 RUDPGetCurrentSendingMaxSeqNo(RUDP_SESSION *se); SOCK *ListenRUDP(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode); SOCK *ListenRUDPEx(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode, volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip); SOCK *AcceptRUDP(SOCK *s); void *InitWaitUntilHostIPAddressChanged(); void FreeWaitUntilHostIPAddressChanged(void *p); void WaitUntilHostIPAddressChanged(void *p, EVENT *event, UINT timeout, UINT ip_check_interval); UINT GetHostIPAddressHash32(); bool GetMyPrivateIP(IP *ip, bool from_vg); char *GetRandHostNameForGetMyPrivateIP(); UINT GenRandInterval(UINT min, UINT max); void RUDPProcess_NatT_Recv(RUDP_STACK *r, UDPPACKET *udp); void RUDPDo_NatT_Interrupt(RUDP_STACK *r); void RUDPGetRegisterHostNameByIP(char *dst, UINT size, IP *ip); bool RUDPParseIPAndPortStr(void *data, UINT data_size, IP *ip, UINT *port); void ParseNtUsername(char *src_username, char *dst_username, UINT dst_username_size, char *dst_domain, UINT dst_domain_size, bool do_not_parse_atmark); void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size); bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size); UINT RUDPCalcBestMssForBulk(RUDP_STACK *r, RUDP_SESSION *se); bool IsIPLocalHostOrMySelf(IP *ip); bool RUDPIsIpInValidateList(RUDP_STACK *r, IP *ip); void RUDPAddIpToValidateList(RUDP_STACK *r, IP *ip); bool GetBestLocalIpForTarget(IP *local_ip, IP *target_ip); SOCK *NewUDP4ForSpecificIp(IP *target_ip, UINT port); #ifdef OS_WIN32 // Function prototype for Win32 void Win32InitSocketLibrary(); void Win32FreeSocketLibrary(); void Win32Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2); void Win32InitAsyncSocket(SOCK *sock); void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event); void Win32FreeAsyncSocket(SOCK *sock); void Win32IpForwardRow2ToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row); void Win32RouteEntryToIpForwardRow2(void *ip_forward_row, ROUTE_ENTRY *entry); int Win32CompareRouteEntryByMetric(void *p1, void *p2); ROUTE_TABLE *Win32GetRouteTable2(bool ipv4, bool ipv6); bool Win32AddRouteEntry2(ROUTE_ENTRY *e, bool *already_exists); void Win32DeleteRouteEntry2(ROUTE_ENTRY *e); UINT Win32GetVLanInterfaceID(char *instance_name); char **Win32EnumVLan(char *tag_name); void Win32Cancel(CANCEL *c); void Win32CleanupCancel(CANCEL *c); CANCEL *Win32NewCancel(); SOCK_EVENT *Win32NewSockEvent(); void Win32SetSockEvent(SOCK_EVENT *event); void Win32CleanupSockEvent(SOCK_EVENT *event); bool Win32WaitSockEvent(SOCK_EVENT *event, UINT timeout); bool Win32GetDefaultDns(IP *ip, char *domain, UINT size); bool Win32GetDnsSuffix(char *domain, UINT size); void Win32FlushDnsCache(); int CompareIpAdapterIndexMap(void *p1, void *p2); ROUTE_CHANGE *Win32NewRouteChange2(bool ipv4, bool ipv6, void *callback); void Win32FreeRouteChange2(ROUTE_CHANGE *r); bool Win32IsRouteChanged2(ROUTE_CHANGE *r); bool Win32GetAdapterFromGuid(void *a, char *guid); SOCKET Win32Accept(SOCK *sock, SOCKET s, struct sockaddr *addr, int *addrlen, bool ipv6); bool Win32ReleaseAddress(void *a); bool Win32ReleaseAddressByGuid(char *guid); bool Win32ReleaseAddressByGuidEx(char *guid, UINT timeout); void Win32ReleaseAddressByGuidExThread(THREAD *t, void *param); void ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM *p); bool Win32ReleaseOrRenewAddressByGuidEx(char *guid, UINT timeout, bool renew); bool Win32RenewAddress(void *a); bool Win32RenewAddressByGuid(char *guid); bool Win32RenewAddressByGuidEx(char *guid, UINT timeout); #else // OS_WIN32 // Function prototype for UNIX void UnixInitSocketLibrary(); void UnixFreeSocketLibrary(); void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2); void UnixInitAsyncSocket(SOCK *sock); void UnixJoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event); void UnixFreeAsyncSocket(SOCK *sock); ROUTE_TABLE *UnixGetRouteTable(); bool UnixAddRouteEntry(ROUTE_ENTRY *e, bool *already_exists); void UnixDeleteRouteEntry(ROUTE_ENTRY *e); UINT UnixGetVLanInterfaceID(char *instance_name); char **UnixEnumVLan(char *tag_name); void UnixCancel(CANCEL *c); void UnixCleanupCancel(CANCEL *c); CANCEL *UnixNewCancel(); SOCK_EVENT *UnixNewSockEvent(); void UnixSetSockEvent(SOCK_EVENT *event); void UnixCleanupSockEvent(SOCK_EVENT *event); bool UnixWaitSockEvent(SOCK_EVENT *event, UINT timeout); bool UnixGetDefaultDns(IP *ip); void UnixNewPipe(int *pipe_read, int *pipe_write); void UnixWritePipe(int pipe_write); void UnixDeletePipe(int p1, int p2); void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout); void UnixSetSocketNonBlockingMode(int fd, bool nonblock); #endif // OS_WIN32 // Function prototype void InitNetwork(); void FreeNetwork(); void InAddrToIP(IP *ip, struct in_addr *addr); void InAddrToIP6(IP *ip, struct in6_addr *addr); void IPToInAddr(struct in_addr *addr, IP *ip); void IPToInAddr6(struct in6_addr *addr, IP *ip); bool StrToIP(IP *ip, char *str); UINT StrToIP32(char *str); UINT UniStrToIP32(wchar_t *str); void IPToStr(char *str, UINT size, IP *ip); void IPToStr32(char *str, UINT size, UINT ip); void IPToStr4or6(char *str, UINT size, UINT ip_4_uint, UCHAR *ip_6_bytes); void IPToUniStr(wchar_t *str, UINT size, IP *ip); void IPToUniStr32(wchar_t *str, UINT size, UINT ip); bool GetHostName(char *hostname, UINT size, IP *ip); void GetMachineName(char *name, UINT size); void GetMachineNameEx(char *name, UINT size, bool no_load_hosts); bool GetMachineNameFromHosts(char *name, UINT size); void GetMachineHostName(char *name, UINT size); void UINTToIP(IP *ip, UINT value); UINT IPToUINT(IP *ip); SOCK *NewSock(); void ReleaseSock(SOCK *s); void CleanupSock(SOCK *s); SOCK *Connect(char *hostname, UINT port); SOCK *ConnectEx(char *hostname, UINT port, UINT timeout); SOCK *ConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag); SOCK *ConnectEx3(char *hostname, UINT port, UINT timeout, bool *cancel_flag, char *nat_t_svc_name, UINT *nat_t_error_code, bool try_start_ssl, bool no_get_hostname); SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, char *nat_t_svc_name, UINT *nat_t_error_code, bool try_start_ssl, bool no_get_hostname, IP *ret_ip); SOCK *ConnectEx5(char *hostname, UINT port, UINT timeout, bool *cancel_flag, char *nat_t_svc_name, UINT *nat_t_error_code, bool try_start_ssl, bool no_get_hostname, SSL_VERIFY_OPTION *ssl_option, UINT *ssl_err, char *hint_str, IP *ret_ip); SOCKET ConnectTimeoutIPv4(IP *ip, UINT port, UINT timeout, bool *cancel_flag); bool SetSocketBufferSize(SOCKET s, bool send, UINT size); UINT SetSocketBufferSizeWithBestEffort(SOCKET s, bool send, UINT size); void InitUdpSocketBufferSize(SOCKET s); void QuerySocketInformation(SOCK *sock); bool SetTtl(SOCK *sock, UINT ttl); void Disconnect(SOCK *sock); SOCK *Listen(UINT port); SOCK *ListenEx(UINT port, bool local_only); SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca, IP *listen_ip); SOCK *ListenEx6(UINT port, bool local_only); SOCK *ListenEx62(UINT port, bool local_only, bool enable_ca); SOCK *ListenEx63(UINT port, bool local_only, bool enable_ca, IP *listen_ip); SOCK *Accept(SOCK *sock); SOCK *Accept6(SOCK *sock); UINT Send(SOCK *sock, void *data, UINT size, bool secure); UINT Recv(SOCK *sock, void *data, UINT size, bool secure); UINT Peek(SOCK *sock, void *data, UINT size); void SetNoNeedToRead(SOCK *sock); UINT SecureSend(SOCK *sock, void *data, UINT size); UINT SecureRecv(SOCK *sock, void *data, UINT size); bool StartSSL(SOCK *sock, X *x, K *priv); bool StartSSLEx(SOCK *sock, X *x, K *priv, UINT ssl_timeout, char *sni_hostname); bool StartSSLEx2(SOCK *sock, X *x, K *priv, LIST *chain, UINT ssl_timeout, char *sni_hostname); bool StartSSLEx3(SOCK *sock, X *x, K *priv, LIST *chain, UINT ssl_timeout, char *sni_hostname, SSL_VERIFY_OPTION *ssl_option, UINT *ssl_err); bool AddChainSslCert(struct ssl_ctx_st *ctx, X *x); void AddChainSslCertOnDirectory(struct ssl_ctx_st *ctx); bool SendAll(SOCK *sock, void *data, UINT size, bool secure); void SendAdd(SOCK *sock, void *data, UINT size); bool SendNow(SOCK *sock, int secure); bool RecvAll(SOCK *sock, void *data, UINT size, bool secure); bool RecvAllEx(SOCK *sock, void **data_new_ptr, UINT size, bool secure); bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure); void InitSockSet(SOCKSET *set); void AddSockSet(SOCKSET *set, SOCK *sock); CANCEL *NewCancel(); CANCEL *NewCancelSpecial(void *hEvent); void ReleaseCancel(CANCEL *c); void CleanupCancel(CANCEL *c); void Cancel(CANCEL *c); void Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2); void SetWantToUseCipher(SOCK *sock, char *name); SOCK *NewUDP(UINT port); SOCK *NewUDPEx(UINT port, bool ipv6); SOCK *NewUDPEx2(UINT port, bool ipv6, IP *ip); SOCK *NewUDPEx3(UINT port, IP *ip); SOCK *NewUDP4(UINT port, IP *ip); SOCK *NewUDP6(UINT port, IP *ip); SOCK *NewUDPEx2Rand(bool ipv6, IP *ip, void *rand_seed, UINT rand_seed_size, UINT num_retry); SOCK *NewUDPEx2RandMachineAndExePath(bool ipv6, IP *ip, UINT num_retry, UCHAR rand_port_id); void ClearSockDfBit(SOCK *s); void SetRawSockHeaderIncludeOption(SOCK *s, bool enable); UINT SendTo(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size); UINT SendToEx(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size, bool broadcast); UINT SendTo6Ex(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size, bool broadcast); UINT RecvFrom(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size); UINT RecvFrom6(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size); void SetTimeout(SOCK *sock, UINT timeout); UINT GetTimeout(SOCK *sock); bool CheckTCPPort(char *hostname, UINT port); bool CheckTCPPortEx(char *hostname, UINT port, UINT timeout); ROUTE_TABLE *GetRouteTable(); void FreeRouteTable(ROUTE_TABLE *t); bool AddRouteEntryEx(ROUTE_ENTRY *e, bool *already_exists); bool AddRouteEntry(ROUTE_ENTRY *e); void DeleteRouteEntry(ROUTE_ENTRY *e); char **EnumVLan(char *tag_name); void FreeEnumVLan(char **s); UINT GetVLanInterfaceID(char *tag_name); ROUTE_ENTRY *GetBestRouteEntry(IP *ip); ROUTE_ENTRY *GetBestRouteEntryEx(IP *ip, UINT exclude_if_id); ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT exclude_if_id); void FreeRouteEntry(ROUTE_ENTRY *e); void JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event); SOCK_EVENT *NewSockEvent(); void SetSockEvent(SOCK_EVENT *event); void CleanupSockEvent(SOCK_EVENT *event); bool WaitSockEvent(SOCK_EVENT *event, UINT timeout); void ReleaseSockEvent(SOCK_EVENT *event); void SetIP(IP *ip, UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4); UINT SetIP32(UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4); bool GetDefaultDns(IP *ip); bool GetDomainName(char *name, UINT size); bool UnixGetDomainName(char *name, UINT size); void AcceptInit(SOCK *s); void AcceptInitEx(SOCK *s, bool no_lookup_hostname); void DisableGetHostNameWhenAcceptInit(); TOKEN_LIST *GetCipherList(); COUNTER *GetNumTcpConnectionsCounter(); void InitWaitThread(); void FreeWaitThread(); void AddWaitThread(THREAD *t); void DelWaitThread(THREAD *t); bool IsSubnetMask(IP *ip); bool IsSubnetMask4(IP *ip); bool IsSubnetMask32(UINT ip); bool IsNetworkAddress4(IP *ip, IP *mask); bool IsNetworkAddress32(UINT ip, UINT mask); bool IsHostIPAddress4(IP *ip); bool IsHostIPAddress32(UINT ip); bool IsZeroIP(IP *ip); bool IsZeroIP6Addr(IPV6_ADDR *addr); UINT IntToSubnetMask32(UINT i); void IntToSubnetMask4(IP *ip, UINT i); bool GetNetBiosName(char *name, UINT size, IP *ip); bool NormalizeMacAddress(char *dst, UINT size, char *src); SOCKLIST *NewSockList(); void StopSockList(SOCKLIST *sl); void FreeSockList(SOCKLIST *sl); bool IsIPv6Supported(); bool HasIPv6Address(); void SetSockTos(SOCK *s, int tos); void SetSockHighPriority(SOCK *s, bool flag); void InitIpClientList(); void FreeIpClientList(); int CompareIpClientList(void *p1, void *p2); void AddIpClient(IP *ip); void DelIpClient(IP *ip); IP_CLIENT *SearchIpClient(IP *ip); UINT GetNumIpClient(IP *ip); void SetLinuxArpFilter(); int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag); ROUTE_CHANGE *NewRouteChange(); void FreeRouteChange(ROUTE_CHANGE *r); bool IsRouteChanged(ROUTE_CHANGE *r); void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e); void DebugPrintRoute(ROUTE_ENTRY *e); void DebugPrintRouteTable(ROUTE_TABLE *r); bool IsIPv6LocalNetworkAddress(IP *ip); void AddProtocolDetailsStr(char *dst, UINT dst_size, char *str); void AddProtocolDetailsKeyValueStr(char *dst, UINT dst_size, char *key, char *value); void AddProtocolDetailsKeyValueInt(char *dst, UINT dst_size, char *key, UINT value); #ifdef ENABLE_SSL_LOGGING void SockEnableSslLogging(SOCK *s); void SockWriteSslLog(SOCK *s, void *send_data, UINT send_size, void *recv_data, UINT recv_size); void SockCloseSslLogging(SOCK *s); #endif // ENABLE_SSL_LOGGING void SocketTimeoutThread(THREAD *t, void *param); SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock); void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp); void CopyIP(IP *dst, IP *src); bool IsIP4(IP *ip); void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr); bool IPToIPv6Addr(IPV6_ADDR *addr, IP *ip); void SetIP6(IP *ip, UCHAR *value); void GetLocalHostIP6(IP *ip); void GetLocalHostIP4(IP *ip); bool IsLocalHostIP6(IP *ip); bool IsLocalHostIP4(IP *ip); bool IsLocalHostIP(IP *ip); void ZeroIP4(IP *ip); bool CheckIPItemStr6(char *str); void IPItemStrToChars6(UCHAR *chars, char *str); bool StrToIP6(IP *ip, char *str); bool StrToIP6Addr(IPV6_ADDR *ip, char *str); void IPToStr6(char *str, UINT size, IP *ip); void IP6AddrToStr(char *str, UINT size, IPV6_ADDR *addr); void IPToStr6Array(char *str, UINT size, UCHAR *bytes); void IPToStr6Inner(char *str, IP *ip); void IntToSubnetMask6(IP *ip, UINT i); void IPAnd6(IP *dst, IP *a, IP *b); void GetAllRouterMulticastAddress6(IP *ip); void GetAllNodeMulticaseAddress6(IP *ip); void GetLoopbackAddress6(IP *ip); UINT GetIPAddrType6(IP *ip); UINT GetIPv6AddrType(IPV6_ADDR *addr); void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet); bool IsInSameNetwork(IP *a1, IP *a2, IP *subnet); bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet); bool IsInSameNetwork6ByStr(char *ip1, char *ip2, char *subnet); void GenerateEui64Address6(UCHAR *dst, UCHAR *mac); void GenerateEui64LocalAddress(IP *a, UCHAR *mac); bool IsSubnetMask6(IP *a); UINT SubnetMaskToInt(IP *a); UINT SubnetMaskToInt6(IP *a); UINT SubnetMaskToInt4(IP *a); bool IsStrIPv6Address(char *str); void IPAnd4(IP *dst, IP *a, IP *b); bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet); bool IsInSameNetwork4Standard(IP *a1, IP *a2); // Utility functions about IP and MAC address types bool IsValidUnicastIPAddress4(IP *ip); bool IsValidUnicastIPAddressUINT4(UINT ip); bool IsValidUnicastIPAddress6(IP *ip); bool IsMacUnicast(UCHAR *mac); bool IsMacBroadcast(UCHAR *mac); bool IsMacMulticast(UCHAR *mac); bool IsMacInvalid(UCHAR *mac); bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask); bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask); bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask); bool ParseIpAndMask6(char *src, IP *ip, IP *mask); bool ParseIpAndMask46(char *src, IP *ip, IP *mask); bool IsIpStr4(char *str); bool IsIpStr6(char *str); bool IsIpMask6(char *str); bool StrToMask6(IP *mask, char *str); bool StrToMask6Addr(IPV6_ADDR *mask, char *str); void MaskToStr(char *str, UINT size, IP *mask); void Mask6AddrToStrEx(char *str, UINT size, IPV6_ADDR *mask, bool always_full_address); void Mask6AddrToStr(char *str, UINT size, IPV6_ADDR *mask); void MaskToStr32(char *str, UINT size, UINT mask); void MaskToStr32Ex(char *str, UINT size, UINT mask, bool always_full_address); void MaskToStrEx(char *str, UINT size, IP *mask, bool always_full_address); TUBEDATA *NewTubeData(void *data, UINT size, void *header, UINT header_size); void FreeTubeData(TUBEDATA *d); TUBE *NewTube(UINT size_of_header); void ReleaseTube(TUBE *t); void CleanupTube(TUBE *t); bool TubeSend(TUBE *t, void *data, UINT size, void *header); bool TubeSendEx(TUBE *t, void *data, UINT size, void *header, bool no_flush); bool TubeSendEx2(TUBE *t, void *data, UINT size, void *header, bool no_flush, UINT max_num_in_queue); void TubeFlush(TUBE *t); void TubeFlushEx(TUBE *t, bool force); TUBEDATA *TubeRecvAsync(TUBE *t); TUBEDATA *TubeRecvSync(TUBE *t, UINT timeout); TUBEPAIR_DATA *NewTubePairData(); void ReleaseTubePairData(TUBEPAIR_DATA *d); void CleanupTubePairData(TUBEPAIR_DATA *d); void NewTubePair(TUBE **t1, TUBE **t2, UINT size_of_header); void TubeDisconnect(TUBE *t); bool IsTubeConnected(TUBE *t); void SetTubeSockEvent(TUBE *t, SOCK_EVENT *e); SOCK_EVENT *GetTubeSockEvent(TUBE *t); TUBE_FLUSH_LIST *NewTubeFlushList(); void FreeTubeFlushList(TUBE_FLUSH_LIST *f); void AddTubeToFlushList(TUBE_FLUSH_LIST *f, TUBE *t); void FlushTubeFlushList(TUBE_FLUSH_LIST *f); LIST *GetHostIPAddressListInternal(); LIST *GetHostIPAddressList(); LIST *CloneIPAddressList(LIST *o); bool IsMyIPAddress(IP *ip); void FreeHostIPAddressList(LIST *o); void AddHostIPAddressToList(LIST *o, IP *ip); int CmpIpAddressList(void *p1, void *p2); UINT64 GetHostIPAddressListHash(); UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param, IP *listen_ip); UDPLISTENER *NewUdpListenerEx(UDPLISTENER_RECV_PROC *recv_proc, void *param, IP *listen_ip, UINT packet_type); void UdpListenerThread(THREAD *thread, void *param); void StopUdpListener(UDPLISTENER *u); void FreeUdpListener(UDPLISTENER *u); void AddPortToUdpListener(UDPLISTENER *u, UINT port); void DeletePortFromUdpListener(UDPLISTENER *u, UINT port); void DeleteAllPortFromUdpListener(UDPLISTENER *u); void UdpListenerSendPackets(UDPLISTENER *u, LIST *packet_list); TCP_RAW_DATA *NewTcpRawData(IP *src_ip, UINT src_port, IP *dst_ip, UINT dst_port); void FreeTcpRawData(TCP_RAW_DATA *trd); UDPPACKET *NewUdpPacket(IP *src_ip, UINT src_port, IP *dst_ip, UINT dst_port, void *data, UINT size); void FreeUdpPacket(UDPPACKET *p); UDPLISTENER_SOCK *DetermineUdpSocketForSending(UDPLISTENER *u, UDPPACKET *p); bool IsUdpPortOpened(UDPLISTENER *u, IP *server_ip, UINT port); INTERRUPT_MANAGER *NewInterruptManager(); void FreeInterruptManager(INTERRUPT_MANAGER *m); void AddInterrupt(INTERRUPT_MANAGER *m, UINT64 tick); UINT GetNextIntervalForInterrupt(INTERRUPT_MANAGER *m); void NewSocketPair(SOCK **client, SOCK **server, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port); SOCK *NewInProcSocket(TUBE *tube_send, TUBE *tube_recv); SOCK *ListenInProc(); SOCK *AcceptInProc(SOCK *s); SOCK *ConnectInProc(SOCK *listen_sock, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port); UINT SendInProc(SOCK *sock, void *data, UINT size); UINT RecvInProc(SOCK *sock, void *data, UINT size); void WaitForTubes(TUBE **tubes, UINT num, UINT timeout); SOCK *ListenReverse(); SOCK *AcceptReverse(SOCK *s); void InjectNewReverseSocketToAccept(SOCK *listen_sock, SOCK *s, IP *client_ip, UINT client_port); bool NewTcpPair(SOCK **s1, SOCK **s2); SOCK *ListenAnyPortEx2(bool local_only, bool disable_ca); ICMP_RESULT *IcmpApiEchoSend(IP *dest_ip, UCHAR ttl, UCHAR *data, UINT size, UINT timeout); void IcmpApiFreeResult(ICMP_RESULT *ret); #ifdef OS_WIN32 void Win32WaitForTubes(TUBE **tubes, UINT num, UINT timeout); #else // OS_WIN32 void UnixWaitForTubes(TUBE **tubes, UINT num, UINT timeout); #endif // OS_WIN32 #define PREVERIFY_ERR_MESSAGE_SIZE 100 // Info on client certificate collected during TLS handshake struct SslClientCertInfo { int PreverifyErr; char PreverifyErrMessage[PREVERIFY_ERR_MESSAGE_SIZE]; X *X; }; SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh); SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert); SSL_PIPE *NewSslPipeEx2(bool server_mode, X *x, K *k, LIST *chain, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert); SSL_PIPE* NewSslPipeEx3(bool server_mode, X* x, K* k, LIST* chain, DH_CTX* dh, bool verify_peer, struct SslClientCertInfo* clientcert, int tls13ticketscnt, bool disableTls13); void FreeSslPipe(SSL_PIPE *s); bool SyncSslPipe(SSL_PIPE *s); SSL_BIO *NewSslBioMem(); SSL_BIO *NewSslBioSsl(); void FreeSslBio(SSL_BIO *b); bool SslBioSync(SSL_BIO *b, bool sync_send, bool sync_recv); void SetCurrentGlobalIP(IP *ip, bool ipv6); bool GetCurrentGlobalIP(IP *ip, bool ipv6); void GetCurrentGlobalIPGuess(IP *ip, bool ipv6); bool IsIPAddressInSameLocalNetwork(IP *a); bool IsIPPrivate(IP *ip); bool IsIPMyHost(IP *ip); void LoadPrivateIPFile(); bool IsOnPrivateIPFile(UINT ip); void FreePrivateIPFile(); LIST *GetNicList(); void FreeNicList(LIST *o); bool IsMacAddressLocalInner(LIST *o, void *addr); bool IsMacAddressLocalFast(void *addr); void RefreshLocalMacAddressList(); struct ssl_ctx_st *NewSSLCtx(bool server_mode); void FreeSSLCtx(struct ssl_ctx_st *ctx); UINT GetOSSecurityLevel(); void SetCurrentDDnsFqdn(char *name); void GetCurrentDDnsFqdn(char *name, UINT size); UINT GetCurrentDDnsFqdnHash(); void DisableRDUPServerGlobally(); void QueryIpThreadMain(THREAD *thread, void *param); QUERYIPTHREAD *NewQueryIpThread(char *hostname, UINT interval_last_ok, UINT interval_last_ng); bool GetQueryIpThreadResult(QUERYIPTHREAD *t, IP *ip); void FreeQueryIpThread(QUERYIPTHREAD *t); #ifdef OS_WIN32 LIST *Win32GetNicList(); #endif // OS_WIN32 void InitDynList(); void FreeDynList(); void AddDynList(BUF *b); void ExtractAndApplyDynList(PACK *p); void SetDynListValue(char *name, UINT64 value); UINT64 GetDynValue(char *name); UINT64 GetDynValueOrDefault(char *name, UINT64 default_value, UINT64 min_value, UINT64 max_value); UINT64 GetDynValueOrDefaultSafe(char *name, UINT64 default_value); #endif // NETWORK_H