Skip to content

Commit bcd84de

Browse files
committed
support single port,many user~
1 parent 75165ec commit bcd84de

File tree

6 files changed

+340
-47
lines changed

6 files changed

+340
-47
lines changed

db_transfer.py

+43-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ def __init__(self):
2525
self.last_update_transfer = {}
2626
self.event = threading.Event()
2727
self.port_uid_table = {}
28+
self.uid_port_table = {}
29+
self.old_md5_users = {}
2830
self.node_speedlimit = 0.00
2931
self.traffic_rate = 0.0
3032

@@ -218,7 +220,7 @@ def pull_db_all_user(self):
218220
switchrule = importloader.load('switchrule')
219221
keys = switchrule.getKeys()
220222
except Exception as e:
221-
keys = ['port', 'u', 'd', 'transfer_enable', 'passwd', 'enable' ,'method','protocol','protocol_param','obfs','obfs_param','node_speedlimit','forbidden_ip','forbidden_port','disconnect_ip']
223+
keys = ['id' , 'port', 'u', 'd', 'transfer_enable', 'passwd', 'enable' ,'method','protocol','protocol_param','obfs','obfs_param','node_speedlimit','forbidden_ip','forbidden_port','disconnect_ip','is_multi_user']
222224

223225
if get_config().MYSQL_SSL_ENABLE == 1:
224226
conn = cymysql.connect(host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER,
@@ -353,6 +355,22 @@ def del_server_out_of_bound_safe(self, last_rows, rows):
353355
logging.error('load switchrule.py fail')
354356
cur_servers = {}
355357
new_servers = {}
358+
359+
md5_users = {}
360+
for row in rows:
361+
md5_users[row['id']] = row.copy()
362+
del md5_users[row['id']]['u']
363+
del md5_users[row['id']]['d']
364+
if md5_users[row['id']]['disconnect_ip'] == None:
365+
md5_users[row['id']]['disconnect_ip'] = ''
366+
367+
if md5_users[row['id']]['forbidden_ip'] == None:
368+
md5_users[row['id']]['forbidden_ip'] = ''
369+
370+
if md5_users[row['id']]['forbidden_port'] == None:
371+
md5_users[row['id']]['forbidden_port'] = ''
372+
md5_users[row['id']]['md5'] = common.get_md5(str(row['id']) + row['passwd'] + row['method'] + row['obfs'] + row['protocol'])
373+
356374
for row in rows:
357375
try:
358376
allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable']
@@ -364,8 +382,9 @@ def del_server_out_of_bound_safe(self, last_rows, rows):
364382
cfg = {'password': passwd}
365383

366384
self.port_uid_table[row['port']] = row['id']
385+
self.uid_port_table[row['id']] = row['port']
367386

368-
read_config_keys = ['method', 'obfs','obfs_param' , 'protocol', 'protocol_param' ,'forbidden_ip', 'forbidden_port' , 'node_speedlimit','forbidden_ip','forbidden_port','disconnect_ip']
387+
read_config_keys = ['method', 'obfs','obfs_param' , 'protocol', 'protocol_param' ,'forbidden_ip', 'forbidden_port' , 'node_speedlimit','forbidden_ip','forbidden_port','disconnect_ip','is_multi_user']
369388

370389
for name in read_config_keys:
371390
if name in row and row[name]:
@@ -398,6 +417,9 @@ def del_server_out_of_bound_safe(self, last_rows, rows):
398417

399418
if 'obfs_param' not in cfg:
400419
cfg['obfs_param'] = ''
420+
421+
if 'is_multi_user' not in cfg:
422+
cfg['is_multi_user'] = 0
401423

402424
if port not in cur_servers:
403425
cur_servers[port] = passwd
@@ -410,7 +432,9 @@ def del_server_out_of_bound_safe(self, last_rows, rows):
410432

411433
cfg['detect_text_list'] = self.detect_text_list.copy()
412434
cfg['detect_hex_list'] = self.detect_hex_list.copy()
413-
435+
436+
cfg['users_table'] = md5_users.copy()
437+
414438

415439
if ServerPool.get_instance().server_is_run(port) > 0:
416440
if not allow:
@@ -422,6 +446,16 @@ def del_server_out_of_bound_safe(self, last_rows, rows):
422446
cfgchange = False
423447
if self.detect_text_ischanged == True or self.detect_hex_ischanged == True:
424448
cfgchange = True
449+
if cmp(self.old_md5_users,md5_users) != 0 and row['is_multi_user'] == 1:
450+
if port in ServerPool.get_instance().tcp_servers_pool:
451+
ServerPool.get_instance().tcp_servers_pool[port].modify_multi_user_table(md5_users)
452+
if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
453+
ServerPool.get_instance().tcp_ipv6_servers_pool[port].modify_multi_user_table(md5_users)
454+
if port in ServerPool.get_instance().udp_servers_pool:
455+
ServerPool.get_instance().udp_servers_pool[port].modify_multi_user_table(md5_users)
456+
if port in ServerPool.get_instance().udp_ipv6_servers_pool:
457+
ServerPool.get_instance().udp_ipv6_servers_pool[port].modify_multi_user_table(md5_users)
458+
425459
if port in ServerPool.get_instance().tcp_servers_pool:
426460
relay = ServerPool.get_instance().tcp_servers_pool[port]
427461
for name in merge_config_keys:
@@ -436,7 +470,7 @@ def del_server_out_of_bound_safe(self, last_rows, rows):
436470
break;
437471
#config changed
438472
if cfgchange:
439-
logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg))
473+
logging.info('db stop server at port [%s] reason: config changed!' % (port))
440474
ServerPool.get_instance().cb_del_server(port)
441475
if port in self.last_update_transfer:
442476
del self.last_update_transfer[port]
@@ -447,7 +481,9 @@ def del_server_out_of_bound_safe(self, last_rows, rows):
447481
protocol = cfg.get('protocol', ServerPool.get_instance().config.get('protocol', 'origin'))
448482
obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain'))
449483
logging.info('db start server at port [%s] pass [%s] protocol [%s] obfs [%s]' % (port, passwd, protocol, obfs))
450-
ServerPool.get_instance().new_server(port, cfg, )
484+
ServerPool.get_instance().new_server(port, cfg)
485+
486+
ServerPool.get_instance().push_uid_port_table(self.uid_port_table)
451487

452488
for row in last_rows:
453489
if row['port'] in cur_servers:
@@ -468,6 +504,8 @@ def del_server_out_of_bound_safe(self, last_rows, rows):
468504
obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain'))
469505
logging.info('db start server at port [%s] pass [%s] protocol [%s] obfs [%s]' % (port, passwd, protocol, obfs))
470506
ServerPool.get_instance().new_server(port, cfg)
507+
508+
self.old_md5_users = md5_users.copy()
471509

472510
@staticmethod
473511
def del_servers():

server_pool.py

+127-14
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ def __init__(self):
6767
self.udp_servers_pool = {}
6868
self.udp_ipv6_servers_pool = {}
6969
self.stat_counter = {}
70+
71+
self.uid_port_table = {}
7072

7173
@staticmethod
7274
def get_instance():
@@ -312,6 +314,35 @@ def get_server_transfer(self, port):
312314
ret[0] += self.udp_ipv6_servers_pool[port].server_transfer_ul
313315
ret[1] += self.udp_ipv6_servers_pool[port].server_transfer_dl
314316
return ret
317+
318+
def get_mu_server_transfer(self, port):
319+
port = int(port)
320+
ret = {}
321+
if port in self.tcp_servers_pool:
322+
tempdict = self.tcp_servers_pool[port].mu_server_transfer_ul
323+
for id in tempdict:
324+
if self.uid_port_table[id] not in ret:
325+
ret[self.uid_port_table[id]] = [0,0]
326+
ret[self.uid_port_table[id]][0] += tempdict[id]
327+
tempdict = self.tcp_servers_pool[port].mu_server_transfer_dl
328+
for id in tempdict:
329+
if self.uid_port_table[id] not in ret:
330+
ret[self.uid_port_table[id]] = [0,0]
331+
ret[self.uid_port_table[id]][1] += tempdict[id]
332+
self.tcp_servers_pool[port]. mu_connected_iplist_clean()
333+
if port in self.tcp_ipv6_servers_pool:
334+
tempdict = self.tcp_ipv6_servers_pool[port].mu_server_transfer_ul
335+
for id in tempdict:
336+
if self.uid_port_table[id] not in ret:
337+
ret[self.uid_port_table[id]] = [0,0]
338+
ret[self.uid_port_table[id]][0] += tempdict[id]
339+
tempdict = self.tcp_ipv6_servers_pool[port].mu_server_transfer_dl
340+
for id in tempdict:
341+
if self.uid_port_table[id] not in ret:
342+
ret[self.uid_port_table[id]] = [0,0]
343+
ret[self.uid_port_table[id]][1] += tempdict[id]
344+
self.tcp_ipv6_servers_pool[port].mu_connected_iplist_clean()
345+
return ret
315346

316347
def get_servers_transfer(self):
317348
servers = self.tcp_servers_pool.copy()
@@ -320,7 +351,15 @@ def get_servers_transfer(self):
320351
servers.update(self.udp_ipv6_servers_pool)
321352
ret = {}
322353
for port in servers.keys():
323-
ret[port] = self.get_server_transfer(port)
354+
if servers[port]._config["is_multi_user"] == 0:
355+
ret[port] = self.get_server_transfer(port)
356+
for port in servers.keys():
357+
if servers[port]._config["is_multi_user"] == 1:
358+
temprets = self.get_mu_server_transfer(port)
359+
for id in temprets:
360+
if id in ret:
361+
ret[id][0] += temprets[id][0]
362+
ret[id][1] += temprets[id][1]
324363
return ret
325364

326365
def get_server_iplist(self, port):
@@ -349,6 +388,54 @@ def get_server_iplist(self, port):
349388
self.udp_ipv6_servers_pool[port].connected_iplist_clean()
350389
return ret
351390

391+
def get_mu_server_iplist(self, port):
392+
port = int(port)
393+
ret = {}
394+
if port in self.tcp_servers_pool:
395+
tempdict = self.tcp_servers_pool[port].mu_connected_iplist
396+
for id in tempdict:
397+
if self.uid_port_table[id] not in ret:
398+
ret[self.uid_port_table[id]] = []
399+
tempret = ret[self.uid_port_table[id]][:]
400+
for ip in tempdict[id]:
401+
tempret.append(ip)
402+
ret[self.uid_port_table[id]] = tempret[:]
403+
self.tcp_servers_pool[port].mu_connected_iplist_clean()
404+
if port in self.tcp_ipv6_servers_pool:
405+
tempdict = self.tcp_ipv6_servers_pool[port].mu_connected_iplist
406+
for id in tempdict:
407+
if self.uid_port_table[id] not in ret:
408+
ret[self.uid_port_table[id]] = []
409+
tempret = ret[self.uid_port_table[id]][:]
410+
for ip in tempdict[id]:
411+
tempret.append(ip)
412+
ret[self.uid_port_table[id]] = tempret[:]
413+
self.tcp_ipv6_servers_pool[port].mu_connected_iplist_clean()
414+
return ret
415+
416+
def get_servers_iplist(self):
417+
servers = self.tcp_servers_pool.copy()
418+
servers.update(self.tcp_ipv6_servers_pool)
419+
servers.update(self.udp_servers_pool)
420+
servers.update(self.udp_ipv6_servers_pool)
421+
ret = {}
422+
for port in servers.keys():
423+
if servers[port]._config["is_multi_user"] == 0:
424+
templist = self.get_server_iplist(port)
425+
if templist != [] :
426+
ret[port] = templist[:]
427+
for port in servers.keys():
428+
if servers[port]._config["is_multi_user"] == 1:
429+
templist = self.get_mu_server_iplist(port)
430+
for id in templist:
431+
for ip in templist[id]:
432+
if id not in ret:
433+
ret[id] = []
434+
if ip not in ret[id]:
435+
tempret = ret[id][:]
436+
tempret.append(ip)
437+
ret[id] = tempret[:]
438+
return ret
352439

353440
def get_servers_detect_log(self):
354441
servers = self.tcp_servers_pool.copy()
@@ -357,9 +444,22 @@ def get_servers_detect_log(self):
357444
servers.update(self.udp_ipv6_servers_pool)
358445
ret = {}
359446
for port in servers.keys():
360-
templist = self.get_server_detect_log(port)
361-
if templist != [] :
362-
ret[port] = templist[:]
447+
if servers[port]._config["is_multi_user"] == 0:
448+
templist = self.get_server_detect_log(port)
449+
if templist != [] :
450+
ret[port] = templist[:]
451+
for port in servers.keys():
452+
if servers[port]._config["is_multi_user"] == 1:
453+
templist = self.get_mu_server_detect_log(port)
454+
for id in templist:
455+
for itemid in templist[id]:
456+
if id not in ret:
457+
ret[id] = []
458+
if itemid not in ret[id]:
459+
tempret = ret[id][:]
460+
tempret.append(itemid)
461+
ret[id] = tempret[:]
462+
363463
return ret
364464

365465

@@ -389,17 +489,27 @@ def get_server_detect_log(self, port):
389489
self.udp_ipv6_servers_pool[port].detect_log_list_clean()
390490
return ret
391491

392-
393-
def get_servers_iplist(self):
394-
servers = self.tcp_servers_pool.copy()
395-
servers.update(self.tcp_ipv6_servers_pool)
396-
servers.update(self.udp_servers_pool)
397-
servers.update(self.udp_ipv6_servers_pool)
492+
def get_mu_server_detect_log(self, port):
493+
port = int(port)
398494
ret = {}
399-
for port in servers.keys():
400-
templist = self.get_server_iplist(port)
401-
if templist != [] :
402-
ret[port] = templist[:]
495+
if port in self.tcp_servers_pool:
496+
tempdict = self.tcp_servers_pool[port].mu_detect_log_list
497+
for id in tempdict:
498+
if self.uid_port_table[id] not in ret:
499+
ret[self.uid_port_table[id]] = []
500+
tempret = ret[self.uid_port_table[id]][:]
501+
for itemid in tempdict[id]:
502+
tempret.append(itemid)
503+
ret[self.uid_port_table[id]] = tempret[:]
504+
if port in self.tcp_ipv6_servers_pool:
505+
tempdict = self.tcp_ipv6_servers_pool[port].mu_detect_log_list
506+
for id in tempdict:
507+
if self.uid_port_table[id] not in ret:
508+
ret[self.uid_port_table[id]] = []
509+
tempret = ret[self.uid_port_table[id]][:]
510+
for itemid in tempdict[id]:
511+
tempret.append(itemid)
512+
ret[self.uid_port_table[id]] = tempret[:]
403513
return ret
404514

405515

@@ -445,3 +555,6 @@ def get_servers_wrong(self):
445555
if templist != [] :
446556
ret[port] = templist[:]
447557
return ret
558+
559+
def push_uid_port_table(self,table):
560+
self.uid_port_table = table

shadowsocks/common.py

+25
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import logging
2424
import binascii
2525
import re
26+
import md5
2627

2728
def compat_ord(s):
2829
if type(s) == int:
@@ -136,6 +137,30 @@ def match_regex(regex,text):
136137
return True
137138
return False
138139

140+
def match_host(data):
141+
return find_between(to_str(data), "Host: ", "\r\n")
142+
143+
def get_md5(data):
144+
m1 = md5.new()
145+
m1.update(data)
146+
return m1.hexdigest()
147+
148+
def find_between( s, first, last ):
149+
try:
150+
start = s.index( first ) + len( first )
151+
end = s.index( last, start )
152+
return s[start:end]
153+
except ValueError:
154+
return ""
155+
156+
def find_between_r( s, first, last ):
157+
try:
158+
start = s.rindex( first ) + len( first )
159+
end = s.rindex( last, start )
160+
return s[start:end]
161+
except ValueError:
162+
return ""
163+
139164
def patch_socket():
140165
if not hasattr(socket, 'inet_pton'):
141166
socket.inet_pton = inet_pton

0 commit comments

Comments
 (0)