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