Skip to content

Instantly share code, notes, and snippets.

@userid
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save userid/816c8a53e97e69e4bfce to your computer and use it in GitHub Desktop.

Select an option

Save userid/816c8a53e97e69e4bfce to your computer and use it in GitHub Desktop.
用python gevent简单实现的server,转发dns请求
#!/usr/bin/python2.7
# Copyright (c) 2012 Denis Bilenko. See LICENSE for details.
"""A simple UDP server.
For every message received, it sends a reply back.
You can use udp_client.py to send a message.
"""
from __future__ import print_function
import argparse,sys
from gevent.server import DatagramServer
from gevent import spawn, joinall,socket,sleep
from Crypto.Cipher import AES
from Crypto.Hash import MD5
TIMEOUT=10
BS = AES.block_size
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]
class ServerConfig:
def __init__(self, arg):
self.server = arg.server
self.port = arg.port
self.key = arg.key
self.timeout= arg.timeout
self.client_mode = arg.client
class EchoServer(DatagramServer):
def __init__(self,address, config):
DatagramServer.__init__(self, address)
self.config = config
self.aes = AES.new(MD5.new(config.key).hexdigest())#, AES.MODE_CBC, IV)
def handle(self, data, address):
print('%s: got(%d) %r' % (address[0], len(data),data))
spawn(self.forward,data, address)
def forward(self,data, address):
client = socket.socket(
family=socket.AF_INET,
type=socket.SOCK_DGRAM,
proto=socket.IPPROTO_UDP)
client.settimeout(self.config.timeout)
aes = self.aes
if self.config.client_mode:
data = aes.encrypt(pad(data))
else:
data = unpad(aes.decrypt(data))
#print('==> got(%d) %r' % (len(data), data))
client.sendto(data, ( self.config.server, self.config.port) )
resp = client.recv(1024)
if self.config.client_mode:
data = unpad(aes.decrypt(resp))
else:
data = aes.encrypt(pad(resp))
self.socket.sendto(data, address)
def parse_arg():
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--server', required=True, help='server ip/host')
parser.add_argument('-p', '--port', required=True, help='server port' ,type=int,)
parser.add_argument('-l', '--local', required=True, help='local listen port' ,default=':10700')
parser.add_argument('-t', '--timeout', help='timeout to connect to server',default=TIMEOUT)
parser.add_argument('-k', '--key', required=True, help='AES encrypt key')
parser.add_argument('-c', '--client', action="store_true", default=False, help='run in client mode')
arg = parser.parse_args()
return arg
if __name__ == '__main__':
arg = parse_arg()
config = ServerConfig(arg)
print('Receiving datagrams on %s' % arg.local )
EchoServer(arg.local , config).serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment