forked from SeattleTestbed/seattlelib_v2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnat_advertisement.r2py
197 lines (137 loc) · 5.28 KB
/
nat_advertisement.r2py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
"""
Author: Armon Dadgar, Eric Kimbrel
Start date: March 27, 2009
Description: Abstracts the task of looking up and advertising servers and forwarders.
"""
dy_import_module_symbols('advertise.r2py')
# What should we register as?
NAT_FORWARDER_ADVERTISE_KEY = "__NAT__FORWARDER__"
NAT_SRV_PREFIX = "__NAT_SRV__"
# Limit of forwarder lookups
NAT_MAX_LOOKUP = 50
NAT_ADVERTISE_INTERVAL = 60
NAT_ADVERTISE_TTL = 3*NAT_ADVERTISE_INTERVAL
# Pools the advertisements, so that they can be done in one thread
# Maps key-> value
NAT_ADVERTISE_POOL = {}
# Enable allows toggling of periodic advertisement
# Run controls the advertisement thread, False will stop the thread
NAT_ADVERTISE_STATE = {"enable":False,"run":False}
# Registers the forwarder so that clients using the NATLayer can find us
def nat_forwarder_advertise(ip, serverport, clientport):
# Generate the value to advertise
value = ip+"*"+str(serverport)+"*"+str(clientport)
# Add to the advertising pool
NAT_ADVERTISE_POOL[NAT_FORWARDER_ADVERTISE_KEY] = value
# Advertises a server, so that other NATLayer users can connect
def nat_server_advertise(key, forwarderIP, forwarderCltPort):
# Generate the value to advertise
value = forwarderIP+'*'+str(forwarderCltPort)
# Alter the key, add the prefix
key = NAT_SRV_PREFIX + key
# Add to the advertising pool
NAT_ADVERTISE_POOL[key] = value
# Stops advertising a server key
def nat_stop_server_advertise(key):
# Alter the key, add the prefix
key = NAT_SRV_PREFIX + key
if key in NAT_ADVERTISE_POOL:
del NAT_ADVERTISE_POOL[key]
# Lookup a forwarder so that we can connect
def nat_forwarder_lookup():
# Get the list of forwarders
forwarders = advertise_lookup(NAT_FORWARDER_ADVERTISE_KEY, NAT_MAX_LOOKUP)
# Safety check..
if len(forwarders) <= 1 and forwarders[0] == '':
raise Exception, "No forwarders could be found!"
# Grab a random forwarder
index = int(randomfloat() * (len(forwarders)-1))
# Get the info
forwarderInfo = forwarders[index]
try:
(ip,server_port,client_port) = forwarderInfo.split('*')
except ValueError:
raise Exception, 'Forwarder lookup returned unexpected value'
# Lookup a forwarder so that we can connect
def nat_forwarder_list_lookup():
# Get the list of forwarders
forwarders = advertise_lookup(NAT_FORWARDER_ADVERTISE_KEY, NAT_MAX_LOOKUP)
# Safety check..
if len(forwarders) <= 1 and forwarders[0] == '':
raise Exception, "No forwarders could be found!"
list = []
for index in range(len(forwarders)):
# Get the info
forwarderInfo = forwarders[index]
try:
(ip,server_port,client_port) = forwarderInfo.split('*')
except ValueError:
raise Exception, 'Forwarder lookup returned unexpected value'
else:
list.append((ip,server_port,client_port))
# Return a tuple containing the IP and port for server and client
return list
# Finds a server using the NATLayer
def nat_server_lookup(key):
# Get the proper key, add the prefix
key = NAT_SRV_PREFIX + key
# Fetch all the keys
lst = advertise_lookup(key, NAT_MAX_LOOKUP)
num = len(lst)
# Safety check...
if num == 0 or (num == 1 and lst[0] == ''):
raise Exception, "Host could not be found!"
# Get the information about the server
info = lst[0]
try:
(forwarder_ip,clt_port) = info.split('*')
except ValueError:
raise 'Unexpected value recieved from server lookup'
# Return a tuple of the forwarder IP port
return (forwarder_ip, int(clt_port))
def nat_server_list_lookup(key):
# Get the proper key, add the prefix
key = NAT_SRV_PREFIX + key
# Get the list of forwarders
servers = advertise_lookup(key, NAT_MAX_LOOKUP)
num = len(servers)
# Safety check...
if num == 0 or (num == 1 and servers[0] == ''):
raise Exception, "Host could not be found!"
list = []
for index in range(num):
# Get the info
info = servers[index]
try:
(forwarder_ip,clt_port) = info.split('*')
except ValueError:
raise Exception, 'lookup returned unexpected value'
else:
list.append((forwarder_ip,clt_port))
# Return a tuple containing the IP and port for server and client
return list
# Toggles advertisement
# Enable: allows or disallows advertisement of the pool
# threadRun: allows/starts or stops the advertisement thread
def nat_toggle_advertisement(enabled, threadRun=True):
NAT_ADVERTISE_STATE["enable"] = enabled
# Start the advertisement thread if necessary
if not NAT_ADVERTISE_STATE["run"] and threadRun:
settimer(.1, _nat_advertise_thread, ())
NAT_ADVERTISE_STATE["run"] = threadRun
# Launch this thread with settimer to handle the advertisement
def _nat_advertise_thread():
while True:
# Check if advertising is enabled:
if NAT_ADVERTISE_STATE["enable"]:
# Advertise everything in the pool
for (key, val) in NAT_ADVERTISE_POOL.items():
try:
advertise_announce(key, val, NAT_ADVERTISE_TTL)
except:
pass
# Sleep for a while
sleep(NAT_ADVERTISE_INTERVAL)
# Check if we should terminate
if not NAT_ADVERTISE_STATE["run"]:
break