Skip to content

Commit d0fe46b

Browse files
committed
feat: add workers support
1 parent 4ce9d80 commit d0fe46b

2 files changed

Lines changed: 47 additions & 62 deletions

File tree

smartdns/sdns.py

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
# version
44
__version__ = '1.0.1.1'
55

6-
import socket
7-
import time
8-
import signal
96
import sys
107
import os
118
import yaml
@@ -18,6 +15,7 @@
1815
from twisted.application import service, internet
1916
from twisted.names import dns, server, client, cache, common, resolve
2017
from twisted.internet import reactor
18+
from multiprocessing import cpu_count, Process
2119
from . import dnsserver, ippool, monitor
2220

2321

@@ -32,74 +30,51 @@ def loadconfig(path):
3230
return yaml.load(f, Loader=yaml.FullLoader)
3331

3432

35-
def get_local_ip():
36-
import sys
37-
import socket
38-
import fcntl
39-
import array
40-
import struct
41-
is_64bits = sys.maxsize > 2**32
42-
struct_size = 40 if is_64bits else 32
43-
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
44-
max_possible = 8 # initial value
45-
while True:
46-
bytes = max_possible * struct_size
47-
names = array.array('B', b'\0' * bytes)
48-
outbytes = struct.unpack('iL', fcntl.ioctl(
49-
s.fileno(),
50-
0x8912, # SIOCGIFCONF
51-
struct.pack('iL', bytes, names.buffer_info()[0])
52-
))[0]
53-
if outbytes == bytes:
54-
max_possible *= 2
55-
else:
56-
break
57-
namestr = names.tostring()
58-
return [(namestr[i:i+16].split(b'\0', 1)[0],
59-
socket.inet_ntoa(namestr[i+20:i+24]))
60-
for i in range(0, outbytes, struct_size)]
61-
62-
6333
def prepare_run(run_env):
64-
# load main config
34+
# load main config
6535
logger.info('start to load %s ......' % run_env['conf'])
6636
conf = loadconfig(os.path.join(run_env['conf'], 'sdns.yaml'))
67-
6837
logger.info('start to load A,SOA,NS record ......')
69-
Amapping = loadconfig(os.path.join(run_env['conf'], 'a.yaml'))
70-
NSmapping = loadconfig(os.path.join(run_env['conf'], 'ns.yaml'))
71-
SOAmapping = loadconfig(os.path.join(run_env['conf'], 'soa.yaml'))
38+
a_mapping = loadconfig(os.path.join(run_env['conf'], 'a.yaml'))
39+
ns_mapping = loadconfig(os.path.join(run_env['conf'], 'ns.yaml'))
40+
soa_mapping = loadconfig(os.path.join(run_env['conf'], 'soa.yaml'))
7241

7342
# start monitor
7443
monitor_config = loadconfig(os.path.join(run_env['conf'], 'monitor.yaml'))
75-
monitor_mapping = monitor.MonitorMapping(monitor_config, Amapping)
44+
monitor_mapping = monitor.MonitorMapping(monitor_config, a_mapping)
7645
# load dns record config file
7746
logger.info('start to init IP pool ......')
78-
Finder = ippool.IPPool(
47+
finder = ippool.IPPool(
7948
os.path.join(run_env['conf'], 'ip.csv'),
8049
os.path.join(run_env['conf'], 'a.yaml'),
8150
monitor_mapping)
8251

83-
run_env['finder'] = Finder
84-
85-
listen_tcp_port = conf['listen']['tcp']
86-
listen_udp_port = conf['listen']['udp']
52+
run_env['finder'] = finder
8753

8854
# set up a resolver that uses the mapping or a secondary nameserver
8955
dnsforward = []
90-
for i in conf['dnsforward_ip']:
91-
dnsforward.append((i, conf['dnsforward_port']))
56+
for i in conf['dnsforward']:
57+
dnsforward_ip, dnsforward_port = i.split(":")
58+
dnsforward.append((dnsforward_ip, int(dnsforward_port)))
9259

93-
for ifc, ip in get_local_ip():
94-
# create the protocols
95-
SmartResolver = dnsserver.MapResolver(
96-
Finder, Amapping, NSmapping, SOAmapping, servers=dnsforward)
60+
# create the protocols
61+
for listen_tcp in conf['listen']['tcp']:
62+
listen_tcp_ip, listen_tcp_port = listen_tcp.split(":")
9763
f = dnsserver.SmartDNSFactory(
98-
caches=[cache.CacheResolver()], clients=[SmartResolver])
99-
p = dns.DNSDatagramProtocol(f)
100-
f.noisy = p.noisy = False
101-
run_env['tcp'].append([listen_tcp_port, f, ip])
102-
run_env['udp'].append([listen_udp_port, p, ip])
64+
caches=[cache.CacheResolver()], clients=[
65+
dnsserver.MapResolver(
66+
finder, a_mapping, ns_mapping, soa_mapping, servers=dnsforward)])
67+
f.noisy = False
68+
run_env['tcp'].append([int(listen_tcp_port), f, listen_tcp_ip])
69+
for listen_udp in conf['listen']['tcp']:
70+
listen_udp_ip, listen_udp_port = listen_udp.split(":")
71+
p = dns.DNSDatagramProtocol(dnsserver.SmartDNSFactory(
72+
caches=[cache.CacheResolver()], clients=[
73+
dnsserver.MapResolver(
74+
finder, a_mapping, ns_mapping, soa_mapping, servers=dnsforward)]))
75+
p.noisy = False
76+
run_env['udp'].append([int(listen_udp_port), p, listen_udp_ip])
77+
return conf
10378

10479

10580
def main():
@@ -109,10 +84,16 @@ def main():
10984
run_env['conf'] = sys.argv[1]
11085
else:
11186
run_env['conf'] = '/etc/smartdns'
112-
113-
prepare_run(run_env)
87+
88+
conf = prepare_run(run_env)
11489
for e in run_env['tcp']:
11590
reactor.listenTCP(e[0], e[1], interface=e[2])
11691
for e in run_env['udp']:
11792
reactor.listenUDP(e[0], e[1], interface=e[2])
118-
reactor.run()
93+
workers = []
94+
for _ in range(conf.get("workers", cpu_count() * 2)):
95+
process = Process(target=reactor.run)
96+
process.daemon = True
97+
process.start()
98+
workers.append(process)
99+
[worker.join() for worker in workers]

templates/sdns.yaml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
#Smart DNS main config file
22

3+
#进程数量
4+
workers: 4
5+
36
#监听端口
47
listen:
5-
tcp: 53
6-
udp: 53
8+
tcp:
9+
- 0.0.0.0:53
10+
udp:
11+
- 0.0.0.0:53
712

813
#dns forward
914
#需要支持多个
10-
dnsforward_ip:
11-
- 119.29.29.29
12-
- 180.76.76.76
13-
dnsforward_port: 53
15+
dnsforward:
16+
- 119.29.29.29:53
17+
- 180.76.76.76:53

0 commit comments

Comments
 (0)