Browse Source

Add parameter "ListenIP" to server configuration (vpn_server.config) (#202)

* Added parameter "ListenIP" to server configuration (vpn_server.config)

* Fixed bug in VPN client
macvk 8 years ago
parent
commit
ab4b27ab3c

+ 3 - 1
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);
 

+ 7 - 2
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++)

+ 1 - 1
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);

+ 10 - 3
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)
 			{

+ 2 - 2
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);
 

+ 1 - 1
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);

+ 7 - 4
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);
 			}
 		}
 	}
@@ -5831,6 +5831,7 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f)
 	}
 
 	s->DontBackupConfig = CfgGetBool(f, "DontBackupConfig");
+	CfgGetIp(f, "ListenIP", &s->ListenIP);
 
 	if (CfgIsItem(f, "BackupConfigOnlyWhenModified"))
 	{
@@ -6287,6 +6288,7 @@ 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);
@@ -10965,8 +10967,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)
@@ -10998,6 +10998,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);
 
 

+ 1 - 0
src/Cedar/Server.h

@@ -368,6 +368,7 @@ struct SERVER
 
 	volatile UINT NatTGlobalUdpPort;	// NAT-T global UDP port
 
+	IP ListenIP;						// Listen IP
 	bool StrictSyslogDatetimeFormat;	// Make syslog datetime format strict RFC3164
 };
 

+ 30 - 13
src/Mayaqua/Network.c

@@ -2729,16 +2729,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;
@@ -5264,7 +5264,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;
@@ -5323,7 +5323,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
@@ -5339,7 +5339,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)
 	{
@@ -5350,7 +5350,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];
@@ -5376,11 +5376,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);
 			}
 		}
 
@@ -14255,9 +14255,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;
@@ -14286,7 +14286,14 @@ 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)
@@ -20119,6 +20126,11 @@ void UdpListenerThread(THREAD *thread, void *param)
 				{
 					IP *ip = LIST_DATA(iplist, i);
 
+					if (CmpIpAddr(ip, &u->ListenIP) != 0)
+					{
+						continue;
+					}
+
 					WriteBuf(ip_list_buf_new, ip, sizeof(IP));
 
 					for (j = 0;j < LIST_NUM(u->PortList);j++)
@@ -20634,7 +20646,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
@@ -20650,6 +20662,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);
 

+ 6 - 5
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,7 @@ 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 +1297,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 +1568,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);