1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-23 01:49:53 +03:00
SoftEtherVPN/src/Mayaqua/Network.h

1475 lines
59 KiB
C

// 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 <openssl/ssl.h> // This is needed only for the SSL/TLS version defines
#ifdef OS_UNIX
#include <netinet/in.h>
#ifdef UNIX_LINUX
#include <pthread.h>
#endif
#ifdef UNIX_OPENBSD
#include <pthread.h>
#endif
#ifdef UNIX_MACOS
#include <pthread.h>
#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