diff --git a/src/Cedar/IPsec.c b/src/Cedar/IPsec.c index ce48c43e..4f71967e 100644 --- a/src/Cedar/IPsec.c +++ b/src/Cedar/IPsec.c @@ -545,6 +545,8 @@ void IPsecServerSetServices(IPSEC_SERVER *s, IPSEC_SERVICES *sl) { Copy(&s->Services, sl, sizeof(IPSEC_SERVICES)); + Copy(&s->UdpListener->ListenIP, &s->Cedar->Server->ListenIP, sizeof(IP)); + if (sl->L2TP_Raw) { AddPortToUdpListener(s->UdpListener, IPSEC_PORT_L2TP); @@ -782,7 +784,7 @@ IPSEC_SERVER *NewIPsecServer(CEDAR *cedar) s->Ike = NewIKEServer(cedar, s); StrCpy(s->Ike->Secret, sizeof(s->Ike->Secret), IPSEC_DEFAULT_SECRET); - s->UdpListener = NewUdpListener(IPsecServerUdpPacketRecvProc, s); + s->UdpListener = NewUdpListener(IPsecServerUdpPacketRecvProc, s, &cedar->Server->ListenIP); s->EtherIPIdList = NewList(CmpEtherIPId); diff --git a/src/Cedar/Interop_OpenVPN.c b/src/Cedar/Interop_OpenVPN.c index 801f48b9..dfe7deb8 100644 --- a/src/Cedar/Interop_OpenVPN.c +++ b/src/Cedar/Interop_OpenVPN.c @@ -2695,7 +2695,7 @@ OPENVPN_SERVER_UDP *NewOpenVpnServerUdp(CEDAR *cedar) AddRef(u->Cedar->ref); // Create a UDP listener - u->UdpListener = NewUdpListener(OpenVpnServerUdpListenerProc, u); + u->UdpListener = NewUdpListener(OpenVpnServerUdpListenerProc, u, &cedar->Server->ListenIP); // Create an OpenVPN server u->OpenVpnServer = NewOpenVpnServer(cedar, u->UdpListener->Interrupts, u->UdpListener->Event); @@ -2704,7 +2704,7 @@ OPENVPN_SERVER_UDP *NewOpenVpnServerUdp(CEDAR *cedar) } // Apply the port list to the OpenVPN server -void OvsApplyUdpPortList(OPENVPN_SERVER_UDP *u, char *port_list) +void OvsApplyUdpPortList(OPENVPN_SERVER_UDP *u, char *port_list, IP *listen_ip) { LIST *o; UINT i; @@ -2716,6 +2716,11 @@ void OvsApplyUdpPortList(OPENVPN_SERVER_UDP *u, char *port_list) DeleteAllPortFromUdpListener(u->UdpListener); + if (u->UdpListener != NULL && listen_ip != NULL) + { + Copy(&u->UdpListener->ListenIP, listen_ip, sizeof(IP)); + } + o = StrToIntList(port_list, true); for (i = 0;i < LIST_NUM(o);i++) diff --git a/src/Cedar/Interop_OpenVPN.h b/src/Cedar/Interop_OpenVPN.h index 20e53bb8..f88ccdc9 100644 --- a/src/Cedar/Interop_OpenVPN.h +++ b/src/Cedar/Interop_OpenVPN.h @@ -319,7 +319,7 @@ struct OPENVPN_SERVER_UDP OPENVPN_SERVER_UDP *NewOpenVpnServerUdp(CEDAR *cedar); void FreeOpenVpnServerUdp(OPENVPN_SERVER_UDP *u); void OpenVpnServerUdpListenerProc(UDPLISTENER *u, LIST *packet_list); -void OvsApplyUdpPortList(OPENVPN_SERVER_UDP *u, char *port_list); +void OvsApplyUdpPortList(OPENVPN_SERVER_UDP *u, char *port_list, IP *listen_ip); OPENVPN_SERVER *NewOpenVpnServer(CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOCK_EVENT *sock_event); void FreeOpenVpnServer(OPENVPN_SERVER *s); diff --git a/src/Cedar/Listener.c b/src/Cedar/Listener.c index b6283208..f1be6225 100644 --- a/src/Cedar/Listener.c +++ b/src/Cedar/Listener.c @@ -356,7 +356,7 @@ void ListenerUDPMainLoop(LISTENER *r) } Debug("NewUDP()\n"); - r->Sock = NewUDP(r->Port); + r->Sock = NewUDPEx2(r->Port, false, &r->Cedar->Server->ListenIP); if (r->Sock != NULL) { // Wait success @@ -465,7 +465,14 @@ void ListenerTCPMainLoop(LISTENER *r) { if (r->ShadowIPv6 == false) { - s = ListenEx2(r->Port, r->LocalOnly, r->EnableConditionalAccept); + if (r->Cedar->Server == NULL) + { + s = ListenEx2(r->Port, r->LocalOnly, r->EnableConditionalAccept, NULL); + } + else + { + s = ListenEx2(r->Port, r->LocalOnly, r->EnableConditionalAccept, &r->Cedar->Server->ListenIP); + } } else { @@ -478,7 +485,7 @@ void ListenerTCPMainLoop(LISTENER *r) } else if (r->Protocol == LISTENER_RUDP) { - s = ListenRUDPEx(VPN_RUDP_SVC_NAME, NULL, ListenerRUDPRpcRecvProc, NULL, 0, false, false, r->NatTGlobalUdpPort, r->RandPortId); + s = ListenRUDPEx(VPN_RUDP_SVC_NAME, NULL, ListenerRUDPRpcRecvProc, NULL, 0, false, false, r->NatTGlobalUdpPort, r->RandPortId, &r->Cedar->Server->ListenIP); } else if (r->Protocol == LISTENER_ICMP) { diff --git a/src/Cedar/Logging.c b/src/Cedar/Logging.c index 69334b14..97ef5dd3 100644 --- a/src/Cedar/Logging.c +++ b/src/Cedar/Logging.c @@ -227,13 +227,13 @@ void SetSysLog(SLOG *g, char *hostname, UINT port) } // Create a syslog client -SLOG *NewSysLog(char *hostname, UINT port) +SLOG *NewSysLog(char *hostname, UINT port, IP *ip) { // Validate arguments SLOG *g = ZeroMalloc(sizeof(SLOG)); g->lock = NewLock(); - g->Udp = NewUDP(0); + g->Udp = NewUDPEx2(0, false, ip); SetSysLog(g, hostname, port); diff --git a/src/Cedar/Logging.h b/src/Cedar/Logging.h index 5457e514..e8f3b801 100644 --- a/src/Cedar/Logging.h +++ b/src/Cedar/Logging.h @@ -263,7 +263,7 @@ LIST *GenerateEraseFileList(ERASER *e); void FreeEraseFileList(LIST *o); void PrintEraseFileList(LIST *o); void EnumEraseFile(LIST *o, char *dirname); -SLOG *NewSysLog(char *hostname, UINT port); +SLOG *NewSysLog(char *hostname, UINT port, IP *ip); void SetSysLog(SLOG *g, char *hostname, UINT port); void FreeSysLog(SLOG *g); void SendSysLog(SLOG *g, wchar_t *str); diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index 191fc147..438157c7 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -159,11 +159,11 @@ void SiSetOpenVPNAndSSTPConfig(SERVER *s, OPENVPN_SSTP_CONFIG *c) { if (s->DisableOpenVPNServer) { - OvsApplyUdpPortList(s->OpenVpnServerUdp, ""); + OvsApplyUdpPortList(s->OpenVpnServerUdp, "", NULL); } else { - OvsApplyUdpPortList(s->OpenVpnServerUdp, s->OpenVpnServerUdpPorts); + OvsApplyUdpPortList(s->OpenVpnServerUdp, s->OpenVpnServerUdpPorts, &s->ListenIP); } } } @@ -5826,6 +5826,8 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f) s->DontBackupConfig = CfgGetBool(f, "DontBackupConfig"); + CfgGetIp(f, "ListenIP", &s->ListenIP); + if (CfgIsItem(f, "BackupConfigOnlyWhenModified")) { s->BackupConfigOnlyWhenModified = CfgGetBool(f, "BackupConfigOnlyWhenModified"); @@ -6279,6 +6281,8 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s) CfgAddBool(f, "DontBackupConfig", s->DontBackupConfig); CfgAddBool(f, "BackupConfigOnlyWhenModified", s->BackupConfigOnlyWhenModified); + CfgAddIp(f, "ListenIP", &s->ListenIP); + if (s->Logger != NULL) { CfgAddInt(f, "ServerLogSwitchType", s->Logger->SwitchType); @@ -10955,8 +10959,6 @@ SERVER *SiNewServerEx(bool bridge, bool in_client_inner_server, bool relay_serve s->Cedar->CheckExpires = true; s->ServerListenerList = NewList(CompareServerListener); s->StartTime = SystemTime64(); - s->Syslog = NewSysLog(NULL, 0); - s->SyslogLock = NewLock(); s->TasksFromFarmControllerLock = NewLock(); if (bridge) @@ -10988,6 +10990,9 @@ SERVER *SiNewServerEx(bool bridge, bool in_client_inner_server, bool relay_serve // Initialize the configuration SiInitConfiguration(s); + s->Syslog = NewSysLog(NULL, 0, &s->Cedar->Server->ListenIP); + s->SyslogLock = NewLock(); + SetFifoCurrentReallocMemSize(MEM_FIFO_REALLOC_MEM_SIZE); diff --git a/src/Cedar/Server.h b/src/Cedar/Server.h index 547df580..9440edd5 100644 --- a/src/Cedar/Server.h +++ b/src/Cedar/Server.h @@ -367,6 +367,8 @@ struct SERVER volatile UINT NatTGlobalUdpPort; // NAT-T global UDP port + + IP ListenIP; // Listen IP }; diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index 41d69cce..16d26d70 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -2724,16 +2724,16 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size) // Start a socket for R-UDP Listening 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) { - return ListenRUDPEx(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, NULL, 0); + return ListenRUDPEx(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, NULL, 0, NULL); } 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) + volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip) { SOCK *s; RUDP_STACK *r; // Creating a R-UDP stack - r = NewRUDPServer(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, natt_global_udp_port, rand_port_id); + r = NewRUDPServer(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, natt_global_udp_port, rand_port_id, listen_ip); if (r == NULL) { return NULL; @@ -5259,7 +5259,7 @@ SOCK *NewRUDPClientDirect(char *svc_name, IP *ip, UINT port, UINT *error_code, U return NULL; } - r = NewRUDP(false, svc_name, NULL, NULL, NULL, local_port, sock, sock_event, false, over_dns_mode, ip, NULL, 0); + r = NewRUDP(false, svc_name, NULL, NULL, NULL, local_port, sock, sock_event, false, over_dns_mode, ip, NULL, 0, NULL); if (r == NULL) { *error_code = RUDP_ERROR_UNKNOWN; @@ -5318,7 +5318,7 @@ SOCK *NewRUDPClientDirect(char *svc_name, IP *ip, UINT port, UINT *error_code, U } // Creating a R-UDP server -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) +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) { RUDP_STACK *r; // Validate arguments @@ -5334,7 +5334,7 @@ RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_inter ListenTcpForPopupFirewallDialog(); - r = NewRUDP(true, svc_name, proc_interrupts, proc_rpc_recv, param, port, NULL, NULL, no_natt_register, over_dns_mode, NULL, natt_global_udp_port, rand_port_id); + r = NewRUDP(true, svc_name, proc_interrupts, proc_rpc_recv, param, port, NULL, NULL, no_natt_register, over_dns_mode, NULL, natt_global_udp_port, rand_port_id, listen_ip); if (r == NULL) { @@ -5345,7 +5345,7 @@ RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_inter } // Creating a R-UDP -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) +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) { RUDP_STACK *r; char tmp[MAX_SIZE]; @@ -5371,11 +5371,11 @@ RUDP_STACK *NewRUDP(bool server_mode, char *svc_name, RUDP_STACK_INTERRUPTS_PROC { if (rand_port_id == 0) { - sock = NewUDP(port); + sock = NewUDPEx2(port, false, listen_ip); } else { - sock = NewUDPEx2RandMachineAndExePath(false, NULL, 0, rand_port_id); + sock = NewUDPEx2RandMachineAndExePath(false, listen_ip, 0, rand_port_id); } } @@ -14241,9 +14241,9 @@ SOCK *Listen(UINT port) } SOCK *ListenEx(UINT port, bool local_only) { - return ListenEx2(port, local_only, false); + return ListenEx2(port, local_only, false, NULL); } -SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca) +SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca, IP *listen_ip) { SOCKET s; SOCK *sock; @@ -14272,7 +14272,13 @@ SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca) SetIP(&localhost, 127, 0, 0, 1); addr.sin_port = htons((UINT)port); - *((UINT *)&addr.sin_addr) = htonl(INADDR_ANY); + if (listen_ip == NULL) + { + *((UINT *)&addr.sin_addr) = htonl(INADDR_ANY); + } else { + IPToInAddr(&addr.sin_addr, listen_ip); + } + addr.sin_family = AF_INET; if (local_only) @@ -20104,6 +20110,11 @@ void UdpListenerThread(THREAD *thread, void *param) for (i = 0;i < LIST_NUM(iplist);i++) { IP *ip = LIST_DATA(iplist, i); + + if ( CmpIpAddr(ip, &u->ListenIP) != 0 ) + { + continue; + } WriteBuf(ip_list_buf_new, ip, sizeof(IP)); @@ -20620,7 +20631,7 @@ void UdpListenerSendPacket(UDPLISTENER *u, UDPPACKET *packet) } // Creating a UDP listener -UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param) +UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param, IP *listen_ip) { UDPLISTENER *u; // Validate arguments @@ -20636,6 +20647,11 @@ UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param) u->PortList = NewList(NULL); u->Event = NewSockEvent(); + if (listen_ip) + { + Copy(&u->ListenIP, listen_ip, sizeof(IP)); + } + u->RecvProc = recv_proc; u->SendPacketList = NewList(NULL); diff --git a/src/Mayaqua/Network.h b/src/Mayaqua/Network.h index b2f42381..06a72ff6 100644 --- a/src/Mayaqua/Network.h +++ b/src/Mayaqua/Network.h @@ -608,6 +608,7 @@ struct UDPLISTENER 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) @@ -1076,9 +1077,9 @@ void ConnectThreadForTcp(THREAD *thread, void *param); void ConnectThreadForRUDP(THREAD *thread, void *param); void ConnectThreadForOverDnsOrIcmp(THREAD *thread, void *param); 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); +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); +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); @@ -1105,7 +1106,8 @@ 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); + volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip); + SOCK *AcceptRUDP(SOCK *s); void *InitWaitUntilHostIPAddressChanged(); void FreeWaitUntilHostIPAddressChanged(void *p); @@ -1296,7 +1298,7 @@ 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); +SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca, IP *listen_ip); SOCK *Listen6(UINT port); SOCK *ListenEx6(UINT port, bool local_only); SOCK *ListenEx62(UINT port, bool local_only, bool enable_ca); @@ -1567,7 +1569,7 @@ void AddHostIPAddressToList(LIST *o, IP *ip); int CmpIpAddressList(void *p1, void *p2); UINT64 GetHostIPAddressListHash(); -UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param); +UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param, IP *listen_ip); void UdpListenerThread(THREAD *thread, void *param); void UdpListenerGetPublicPortList(UDPLISTENER *u, char *dst, UINT size); void FreeUdpListener(UDPLISTENER *u);