Browse Source

feat: basic demo of working process

master
dnomd343 2 years ago
parent
commit
06b097c720
  1. 64
      Basis/Api.py
  2. 50
      Basis/Check.py
  3. 7
      Basis/Manage.py
  4. 29
      demo.py
  5. 43
      main.py

64
Basis/Api.py

@ -3,6 +3,7 @@
import json import json
from gevent import pywsgi from gevent import pywsgi
from Basis.Manage import Manage
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Constant import Version from Basis.Constant import Version
from flask import Flask, Response, request from flask import Flask, Response, request
@ -37,35 +38,80 @@ def tokenCheck() -> bool:
def getTaskList() -> Response: def getTaskList() -> Response:
if not tokenCheck(): # token check if not tokenCheck(): # token check
return tokenError() return tokenError()
logging.critical('get task list') try:
return jsonResponse({}) taskList = Manage.listTask()
logging.debug('api get task list -> %s' % taskList)
return jsonResponse({
'success': True,
'task': taskList,
})
except:
return jsonResponse({
'success': False,
'message': 'Unknown error'
})
@webApi.route('/task', methods = ['POST']) @webApi.route('/task', methods = ['POST'])
def createTask() -> Response: def createTask() -> Response:
if not tokenCheck(): # token check if not tokenCheck(): # token check
return tokenError() return tokenError()
logging.critical('create task') checkList = request.json.get('check')
return jsonResponse({}) proxyList = request.json.get('proxy')
if checkList is None or type(checkList) != list:
return jsonResponse({
'success': False,
'message': 'invalid check list',
})
if proxyList is None or type(proxyList) != list:
return jsonResponse({
'success': False,
'message': 'invalid proxy list',
})
logging.debug('api create task -> check: %s | proxy: %s' % (checkList, proxyList))
# TODO: format check and proxy list
tasks = []
for proxy in proxyList:
tasks.append({**proxy, 'check': checkList})
checkId = Manage.addTask(tasks)
logging.debug('api return check id %s' % checkId)
return jsonResponse({
'success': True,
'id': checkId,
'check': checkList,
'proxy': proxyList,
})
@webApi.route('/task/<taskId>', methods = ['GET']) @webApi.route('/task/<taskId>', methods = ['GET'])
def getTaskInfo() -> Response: def getTaskInfo(taskId: str) -> Response:
if not tokenCheck(): # token check if not tokenCheck(): # token check
return tokenError() return tokenError()
logging.critical('get task info') logging.critical('API get task %s info' % taskId)
return jsonResponse({}) if not Manage.isTask(taskId):
return jsonResponse({
'success': False,
'message': 'task id not found',
})
return jsonResponse({
'success': True,
**Manage.getTask(taskId)
})
@webApi.route('/version', methods = ['GET']) @webApi.route('/version', methods = ['GET'])
def getVersion() -> Response: def getVersion() -> Response:
logging.debug('get version -> %s' + Version) logging.debug('get version -> %s' + Version)
return jsonResponse({ return jsonResponse({
'version': Version 'success': True,
'version': Version,
}) })
def startServer(apiPort: int = 7839, apiToken: str = '') -> None: def startServer(apiToken: str = '', apiPort: int = 7839) -> None:
global token global token
token = apiToken token = apiToken
logging.warning('API server at http://:%i/' % apiPort) logging.warning('API server at http://:%i/' % apiPort)

50
Basis/Check.py

@ -0,0 +1,50 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
from Basis.Logger import logging
from Builder import Builder, clientEntry
from ProxyChecker import httpCheck # TODO: refactor in the future
def Check(proxyType: str, proxyInfo: dict, checkInfo: dict) -> dict:
# TODO: checkInfo -> [...] (only check http for now)
if proxyType not in clientEntry:
logging.error('Unknown proxy type %s' % proxyType)
raise RuntimeError('Unknown proxy type')
try:
client = Builder(proxyType, proxyInfo)
except Exception as reason:
logging.error('Client build error -> %s' % reason)
raise RuntimeError('Client build error')
# TODO: debug combine output
logging.debug(client.id)
logging.debug(client.proxyType)
logging.debug(client.proxyInfo)
logging.debug(client.socksAddr)
logging.debug(client.socksPort)
# TODO: wait port occupied
time.sleep(1)
if not client.status(): # client unexpected exit
client.destroy() # remove file and kill sub process
logging.error('Client unexpected exit\n%s', client.output)
raise RuntimeError('Client unexpected exit')
# TODO: check process
status, _ = httpCheck(client.socksPort) # TODO: add socks5 addr
logging.critical('http check status -> %s' % status)
client.destroy() # clean up the client
return {
'http': {
'status': status,
# TODO: more http check info
},
# TODO: more check items (from checkInfo list)
}

7
Basis/Manage.py

@ -50,9 +50,8 @@ class Task(object):
if completed < len(subList): # some sub tasks are not completed if completed < len(subList): # some sub tasks are not completed
logging.debug('[%s] task still running' % taskId) logging.debug('[%s] task still running' % taskId)
return { return {
'done': False, 'finish': False,
'total': len(subList), 'percent': '%i%%' % (completed / len(subList))
'finish': completed,
} }
logging.debug('[%s] task work complete' % taskId) # all sub tasks completed logging.debug('[%s] task work complete' % taskId) # all sub tasks completed
result = [] result = []
@ -62,7 +61,7 @@ class Task(object):
result.append(subTask['data']) result.append(subTask['data'])
logging.debug('release sub tasks -> %s' % result) logging.debug('release sub tasks -> %s' % result)
return { return {
'done': True, 'finish': True,
'result': result 'result': result
} }

29
demo.py

@ -132,17 +132,20 @@ proxyHysteria = {
# client = Builder('trojan', proxyTrojan) # client = Builder('trojan', proxyTrojan)
# client = Builder('trojan-go', proxyTrojanGo) # client = Builder('trojan-go', proxyTrojanGo)
# client = Builder('brook', proxyBrook) # client = Builder('brook', proxyBrook)
client = Builder('hysteria', proxyHysteria) # client = Builder('hysteria', proxyHysteria)
#
# logging.critical(client.id)
# logging.critical(client.proxyType)
# logging.critical(client.proxyInfo)
# logging.critical(client.socksAddr)
# logging.critical(client.socksPort)
#
# time.sleep(15)
# logging.critical(client.status())
#
# client.destroy()
# logging.critical(client.status())
# logging.critical('Client output:\n' + str(client.output))
logging.critical(client.id) from Basis.Check import Check
logging.critical(client.proxyType) Check('ss', proxySS, {})
logging.critical(client.proxyInfo)
logging.critical(client.socksAddr)
logging.critical(client.socksPort)
time.sleep(15)
logging.critical(client.status())
client.destroy()
logging.critical(client.status())
logging.critical('Client output:\n' + str(client.output))

43
main.py

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
import time import time
import _thread import _thread
import subprocess import subprocess
@ -9,21 +9,28 @@ from Basis.Api import startServer
from Basis.Constant import Version from Basis.Constant import Version
from Basis.Compile import startCompile from Basis.Compile import startCompile
dnsServers = None
# dnsServers = ['223.5.5.5', '119.28.28.28']
def startDnsproxy(command: list) -> subprocess.Popen: def startDnsproxy(command: list) -> subprocess.Popen:
logging.debug('start dnsproxy -> %s' % command) logging.debug('start dnsproxy -> %s' % command)
return subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) return subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
def daemonDnsproxy(dnsServers: list, localPort: int = 53, cacheSize: int = 4194304) -> None: # default cache -> 4MiB def daemonDnsproxy(servers: list or None, port: int = 53, cache: int = 4194304) -> None: # default cache size -> 4MiB
logging.info('start dnsproxy at port %i -> %s' % (localPort, dnsServers)) if servers is None or len(servers) == 0:
logging.info('skip dnsproxy process')
return
logging.info('start dnsproxy at port %i -> %s' % (port, servers))
os.system('echo "nameserver 127.0.0.1" > /etc/resolv.conf') # system dns settings
dnsCommand = [ dnsCommand = [
'dnsproxy', '--all-servers', 'dnsproxy', '--all-servers',
'--port', str(localPort), '--port', str(port),
'--cache', '--cache-size', str(cacheSize) '--cache', '--cache-size', str(cache)
] ]
for dnsServer in dnsServers: for server in servers:
dnsCommand += ['--upstream', dnsServer] dnsCommand += ['--upstream', server]
dnsproxy = startDnsproxy(dnsCommand) dnsproxy = startDnsproxy(dnsCommand)
while True: while True:
time.sleep(2) # daemon time gap time.sleep(2) # daemon time gap
@ -33,10 +40,24 @@ def daemonDnsproxy(dnsServers: list, localPort: int = 53, cacheSize: int = 41943
dnsproxy = startDnsproxy(dnsCommand) dnsproxy = startDnsproxy(dnsCommand)
logging.warning('ProxyC starts running (%s)' % Version) from Basis.Check import Check
from Basis.Manage import Manage
_thread.start_new_thread(startCompile, ('/usr', )) def loopCheck() -> None:
while True:
time.sleep(2) # TODO: thread pool working
subTaskId, subTask = Manage.popSubTask()
if subTaskId is None: continue
logging.info('new sub task -> %s', subTask)
ret = Check(subTask['type'], subTask['info'], {})
logging.info('check result -> %s' % ret)
subTask.pop('check')
subTask['result'] = ret
Manage.updateSubTask(subTaskId, subTask)
_thread.start_new_thread(daemonDnsproxy, (['223.5.5.5', '119.28.28.28'], 53))
startServer(apiToken = 'dnomd343') logging.warning('ProxyC starts running (%s)' % Version)
_thread.start_new_thread(startCompile, ('/usr', )) # python compile (generate .pyc file)
_thread.start_new_thread(daemonDnsproxy, (dnsServers, 53)) # set system's dns server
_thread.start_new_thread(loopCheck, ()) # start loop check
startServer(apiToken = '') # start api server

Loading…
Cancel
Save