mirror of https://github.com/dnomd343/ProxyC
Dnomd343
3 years ago
1 changed files with 105 additions and 96 deletions
@ -1,96 +1,105 @@ |
|||||
#!/usr/bin/python |
#!/usr/bin/python |
||||
# -*- coding:utf-8 -*- |
# -*- coding:utf-8 -*- |
||||
|
|
||||
import time |
import os |
||||
import ctypes |
import time |
||||
import random |
import ctypes |
||||
import socket |
import random |
||||
import subprocess |
import socket |
||||
from ProxyBuilder import Shadowsocks |
import subprocess |
||||
|
from ProxyBuilder import Shadowsocks |
||||
# TODO: find in multi path |
|
||||
libcPath = '/lib/libc.musl-x86_64.so.1' # for Alpine |
libcPaths = [ |
||||
|
'/usr/lib64/libc.so.6', # CentOS |
||||
# TODO: TCP/UDP IPv4/IPv6 |
'/lib/i386-linux-gnu/libc.so.6', # Debian / Ubuntu |
||||
def __checkPortAvailable(port, host = '127.0.0.1'): # 检测端口可用性 |
'/lib/x86_64-linux-gnu/libc.so.6', |
||||
s = None |
'/lib/aarch64-linux-gnu/libc.so.6', |
||||
try: |
'/lib/libc.musl-x86_64.so.1', # Alpine |
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
] |
||||
s.settimeout(1) |
|
||||
s.connect((host, int(port))) |
# TODO: TCP/UDP IPv4/IPv6 |
||||
return False |
def __checkPortAvailable(port, host = '127.0.0.1'): # 检测端口可用性 |
||||
except socket.error: |
s = None |
||||
return True |
try: |
||||
finally: |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
||||
if s: |
s.settimeout(1) |
||||
s.close() |
s.connect((host, int(port))) |
||||
|
return False |
||||
def __genTaskFlag(length = 16): # 生成任务代号 |
except socket.error: |
||||
flag = "" |
return True |
||||
for i in range(0, length): |
finally: |
||||
tmp = random.randint(0, 15) |
if s: |
||||
if tmp >= 10: |
s.close() |
||||
flag += chr(tmp + 87) # a ~ f |
|
||||
else: |
def __genTaskFlag(length = 16): # 生成任务代号 |
||||
flag += str(tmp) # 0 ~ 9 |
flag = "" |
||||
return flag |
for i in range(0, length): |
||||
|
tmp = random.randint(0, 15) |
||||
def __getAvailablePort(rangeStart, rangeEnd): # 获取一个空闲端口 |
if tmp >= 10: |
||||
if rangeStart > rangeEnd: |
flag += chr(tmp + 87) # a ~ f |
||||
return None |
else: |
||||
while True: |
flag += str(tmp) # 0 ~ 9 |
||||
port = random.randint(rangeStart, rangeEnd) # 随机选取 |
return flag |
||||
if __checkPortAvailable(port): |
|
||||
return port |
def __getAvailablePort(rangeStart, rangeEnd): # 获取一个空闲端口 |
||||
time.sleep(0.1) # 100ms |
if rangeStart > rangeEnd: |
||||
|
return None |
||||
def build(proxyInfo, configDir): # 构建代理节点连接 |
while True: |
||||
taskFlag = __genTaskFlag() |
port = random.randint(rangeStart, rangeEnd) # 随机选取 |
||||
socksPort = __getAvailablePort(1024, 65535) # Socks5测试端口 |
if __checkPortAvailable(port): |
||||
if not 'type' in proxyInfo: |
return port |
||||
return None |
time.sleep(0.1) # 100ms |
||||
proxyType = proxyInfo['type'] # 节点类型 |
|
||||
proxyInfo.pop('type') |
def build(proxyInfo, configDir): # 构建代理节点连接 |
||||
|
taskFlag = __genTaskFlag() |
||||
configFile = configDir + '/' + taskFlag + '.json' # 配置文件路径 |
socksPort = __getAvailablePort(1024, 65535) # Socks5测试端口 |
||||
if (proxyType == 'shadowsocks'): # Shadowsocks节点 |
if not 'type' in proxyInfo: |
||||
startCommand = Shadowsocks.load(proxyInfo, socksPort, configFile) |
return None |
||||
else: # 未知类型 |
proxyType = proxyInfo['type'] # 节点类型 |
||||
return None |
proxyInfo.pop('type') |
||||
|
|
||||
try: |
configFile = configDir + '/' + taskFlag + '.json' # 配置文件路径 |
||||
exitWithMe = lambda: ctypes.CDLL(libcPath).prctl(1, 15) # SIGTERM |
if (proxyType == 'shadowsocks'): # Shadowsocks节点 |
||||
process = subprocess.Popen(startCommand, \ |
startCommand = Shadowsocks.load(proxyInfo, socksPort, configFile) |
||||
stdout = subprocess.DEVNULL, \ |
else: # 未知类型 |
||||
stderr = subprocess.DEVNULL, \ |
return None |
||||
preexec_fn = exitWithMe) # 子进程跟随退出 |
|
||||
except: |
try: |
||||
process = subprocess.Popen(startCommand, \ |
for libcPath in libcPaths: |
||||
stdout = subprocess.DEVNULL, \ |
if os.path.exists(libcPath): # 定位libc.so文件 |
||||
stderr = subprocess.DEVNULL) # prctl失败 回退正常启动 |
break |
||||
|
exitWithMe = lambda: ctypes.CDLL(libcPath).prctl(1, 15) # SIGTERM |
||||
return { # 返回连接参数 |
process = subprocess.Popen(startCommand, \ |
||||
'flag': taskFlag, |
stdout = subprocess.DEVNULL, \ |
||||
'port': socksPort, |
stderr = subprocess.DEVNULL, \ |
||||
'file': configFile, |
preexec_fn = exitWithMe) # 子进程跟随退出 |
||||
'process': process, |
except: |
||||
'pid': process.pid, |
process = subprocess.Popen(startCommand, \ |
||||
} |
stdout = subprocess.DEVNULL, \ |
||||
|
stderr = subprocess.DEVNULL) # prctl失败 回退正常启动 |
||||
def check(taskInfo): # 检查客户端是否正常 |
|
||||
process = taskInfo['process'] |
return { # 返回连接参数 |
||||
if process.poll() != None: |
'flag': taskFlag, |
||||
return False # 死亡 |
'port': socksPort, |
||||
else: |
'file': configFile, |
||||
return True # 正常 |
'process': process, |
||||
|
'pid': process.pid, |
||||
def destroy(taskInfo): # 结束客户端并清理 |
} |
||||
process = taskInfo['process'] |
|
||||
if process.poll() == None: # 未死亡 |
def check(taskInfo): # 检查客户端是否正常 |
||||
process.terminate() # SIGTERM |
process = taskInfo['process'] |
||||
while process.poll() == None: # 等待退出 |
if process.poll() != None: |
||||
time.sleep(1) |
return False # 死亡 |
||||
process.terminate() |
else: |
||||
try: |
return True # 正常 |
||||
os.remove(taskInfo.file) # 删除配置文件 |
|
||||
except: pass |
def destroy(taskInfo): # 结束客户端并清理 |
||||
|
process = taskInfo['process'] |
||||
|
if process.poll() == None: # 未死亡 |
||||
|
process.terminate() # SIGTERM |
||||
|
while process.poll() == None: # 等待退出 |
||||
|
time.sleep(1) |
||||
|
process.terminate() |
||||
|
try: |
||||
|
os.remove(taskInfo.file) # 删除配置文件 |
||||
|
except: pass |
||||
|
Loading…
Reference in new issue