1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Cedar Communication Module
3 
4 
5 // SecureNAT.c
6 // SecureNAT code
7 
8 #include "SecureNAT.h"
9 
10 #include "Connection.h"
11 #include "Hub.h"
12 #include "Logging.h"
13 #include "Nat.h"
14 #include "Session.h"
15 
16 #include "Mayaqua/Kernel.h"
17 #include "Mayaqua/Memory.h"
18 #include "Mayaqua/Object.h"
19 #include "Mayaqua/Str.h"
20 
21 // SecureNAT server-side thread
SnSecureNATThread(THREAD * t,void * param)22 void SnSecureNATThread(THREAD *t, void *param)
23 {
24 	SNAT *s;
25 	CONNECTION *c;
26 	SESSION *se;
27 	POLICY *policy;
28 	HUB *h;
29 	// Validate arguments
30 	if (t == NULL || param == NULL)
31 	{
32 		return;
33 	}
34 
35 	s = (SNAT *)param;
36 	// Create a server connection
37 	c = NewServerConnection(s->Cedar, NULL, t);
38 	c->Protocol = CONNECTION_HUB_SECURE_NAT;
39 
40 	// Apply the default policy
41 	policy = ClonePolicy(GetDefaultPolicy());
42 
43 	// Not to limit the number of broadcast
44 	policy->NoBroadcastLimiter = true;
45 
46 	h = s->Hub;
47 	AddRef(h->ref);
48 
49 	// create a server session
50 	se = NewServerSession(s->Cedar, c, s->Hub, SNAT_USER_NAME, policy);
51 	se->SecureNATMode = true;
52 	se->SecureNAT = s;
53 	c->Session = se;
54 	ReleaseConnection(c);
55 
56 	HLog(se->Hub, "LH_NAT_START", se->Name);
57 
58 	// User name
59 	se->Username = CopyStr(SNAT_USER_NAME_PRINT);
60 
61 	s->Session = se;
62 	AddRef(se->ref);
63 
64 	// Notification initialization completion
65 	NoticeThreadInit(t);
66 
67 	ReleaseCancel(s->Nat->Virtual->Cancel);
68 	s->Nat->Virtual->Cancel = se->Cancel1;
69 	AddRef(se->Cancel1->ref);
70 
71 	if (s->Nat->Virtual->NativeNat != NULL)
72 	{
73 		CANCEL *old_cancel = NULL;
74 
75 		Lock(s->Nat->Virtual->NativeNat->CancelLock);
76 		{
77 			if (s->Nat->Virtual->NativeNat->Cancel != NULL)
78 			{
79 				old_cancel = s->Nat->Virtual->NativeNat->Cancel;
80 
81 				s->Nat->Virtual->NativeNat->Cancel = se->Cancel1;
82 
83 				AddRef(se->Cancel1->ref);
84 			}
85 		}
86 		Unlock(s->Nat->Virtual->NativeNat->CancelLock);
87 
88 		if (old_cancel != NULL)
89 		{
90 			ReleaseCancel(old_cancel);
91 		}
92 	}
93 
94 	// Main function of the session
95 	Debug("SecureNAT Start.\n");
96 	SessionMain(se);
97 	Debug("SecureNAT Stop.\n");
98 
99 	HLog(se->Hub, "LH_NAT_STOP");
100 
101 	ReleaseHub(h);
102 
103 	ReleaseSession(se);
104 }
105 
106 // Release the SecureNAT
SnFreeSecureNAT(SNAT * s)107 void SnFreeSecureNAT(SNAT *s)
108 {
109 	// Validate arguments
110 	if (s == NULL)
111 	{
112 		return;
113 	}
114 
115 	// Stop the session
116 	StopSession(s->Session);
117 	ReleaseSession(s->Session);
118 
119 	// Virtual machine release
120 	Virtual_Free(s->Nat->Virtual);
121 
122 	// NAT release
123 	NiFreeNat(s->Nat);
124 
125 	DeleteLock(s->lock);
126 
127 	Free(s);
128 }
129 
130 // Create a new SecureNAT
SnNewSecureNAT(HUB * h,VH_OPTION * o)131 SNAT *SnNewSecureNAT(HUB *h, VH_OPTION *o)
132 {
133 	SNAT *s;
134 	THREAD *t;
135 	// Validate arguments
136 	if (h == NULL || o == NULL)
137 	{
138 		return NULL;
139 	}
140 
141 	s = ZeroMalloc(sizeof(SNAT));
142 	s->Cedar = h->Cedar;
143 	s->Hub = h;
144 	s->lock = NewLock();
145 
146 	// Create a NAT
147 	s->Nat = NiNewNatEx(s, o);
148 
149 	// Initialize the virtual machine
150 	VirtualInit(s->Nat->Virtual);
151 
152 	// Create a thread
153 	t = NewThread(SnSecureNATThread, s);
154 	WaitThreadInit(t);
155 	ReleaseThread(t);
156 
157 	return s;
158 }
159 
160