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