Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import socket
- import sys
- from os.path import exists,getsize
- import os
- import time
- import threading
- import math
- # virtual guest os:es set to
- # Generic Driver
- # Name=UDPTunnel
- # !check advanced
- # Generic Properties
- # dest=UDP RELAY SERVER HOST EXTERNAL IP (local ip on server host guest (0th client))
- # sport=ROUTED PORT INTERNET (port to send packets from SERVER(udp_relay_server) (setting name listen (tuple(tuple(ip,port),mac,tuple(ip,port),mac))) (client shouldn't need to routed if packets are sent before server is running (server still routed))
- # dport=RELAY SERVER ROUTED PORT (setting name serverport)
- #encryption support missing (data will be visible to middleman attacks)
- serverport=27000 # port to host UDP RELAY SERVER (packet distributor)
- clientused=[0,1,2,3]
- listen= (('192.168.100.20',26000),b'\x08\x00\x27\xff\xff\xff', # 0th enter here your own local ip + sport of virtual machine + your guest os virtual network card mac
- ('123.123.123.123',26000),b'\x08\x00\x27\xff\xff\xff', # 1st client ip of his/her host + sport value + 1st client guest os virtual network card mac
- ('231.231.231.231',26000),b'\x08\x00\x27\xff\xff\xff', # 2nd client ip of his/her host + sport value + 2nd client guest os virtual network card mac
- ('213.213.213.213',26000),b'\x08\x00\x27\xff\xff\xff') # 3rd client ip of his/her host + sport value + 3rd client guest os virtual network card mac
- data_payload = 2048 #max packet size (shouldn't need to be on mtu, preferably over it (low value will split packets and UDP RELAY SERVER cannot handle split packets))
- allclientsbroadcast = True #if false, only server host (0) packets broadcast packets are transmitted to all. this may cause some NOT seeing on other hosts hosted games.
- broadcastonlyactive = True #if true, broadcast packets are only sent clients that have connected UDP RELAY SERVER (activates settings defaultstate,droptimeout and droppedremind)
- defaultstate= True #starting state of client DROPPED status
- displayfake = True #reports even if broadcastonlyactive is false on timeouts.
- droptimeout = 360 #seconds clients are to remain in packet target if no connection from them.
- droppedremind = 120 #seconds bethween reminding dropped clients.
- logfilename="logfile" #log for umatching connections (cannot be disabled) (you can provide file address here)
- logfileext=".txt"
- #NO MORE SETTINGS TO CONFIGURE AFTER THIS LINE
- macbroad=b'\xff\xff\xff\xff\xff\xff' #do not touch (broadcast mac address)
- clientamount=4 #does nothing (gets auto set by clientused)
- clienttime=[]
- logifile=open(logfilename + logfileext, 'a')
- prevpri=time.time() - 10.0
- def listeshow():
- global prevpri
- while True:
- if prevpri + 2.5 < time.time():
- print ("[%03d] Waiting to receive message from client" % (math.floor(time.time())%1000) )
- return
- time.sleep(0.05)
- def dropfollow():
- global clienttime
- global clientused
- while True:
- for x in clientused:
- if clienttime[x*2] + droptimeout < time.time() and not clienttime[x*2+1]:
- print("[%03d] %s dropped from connection.%s" % (math.floor(time.time())%1000,listen[x*2],"fake" if not broadcastonlyactive else ""))
- clienttime[x*2+1]=True
- clienttime[x*2]=time.time()
- elif clienttime[x*2+1] and clienttime[x*2] + droppedremind < time.time():
- print("[%03d] %s still down...%s" % (math.floor(time.time())%1000,listen[x*2],"fake" if not broadcastonlyactive else ""))
- clienttime[x*2]=time.time()
- time.sleep(1.0)
- def mysendpacket(sock,data,target):
- try:
- return sock.sendto(data,target)
- except Exception as e:
- console.writeError(str(e))
- return -1
- def echo_server(port):
- # Create a UDP socket
- sock = socket.socket(socket.AF_INET,
- socket.SOCK_DGRAM)
- # Bind the socket to the port
- server_address = (listen[0][0], port)
- global logifile
- global clienttime
- global clientused
- if exists(logfilename + logfileext):
- if os.path.getsize(logfilename + logfileext) == 0:
- pass
- else:
- if exists(logfilename + "9" + logfileext):
- os.remove(logfilename + "9" + logfileext)
- for x in range(8,0,-1):
- if exists((logfilename + "%s" + logfileext) % x):
- os.rename((logfilename + "%s" + logfileext) % x,(logfilename + "%s" + logfileext) % (x+1))
- logifile.close()
- os.rename(logfilename + logfileext,(logfilename + "1" + logfileext))
- logifile=open(logfilename + logfileext,"x")
- else:
- logifile=open(logfilename + logfileext,"x")
- tmp=[]
- for i in clientused:
- if i not in tmp and i < math.floor(len(listen)/2):
- tmp.append(i)
- print("Allowed %d %s client." % (i,listen[i*2]))
- else:
- print("Unlisted %d (max id %d) client. (if already allowed it's still listed)" % (i,math.floor(len(listen)/2)-1))
- clientused=tmp
- del tmp
- clientamount=len(clientused)
- for i in range(0,math.floor(len(listen)/2)):
- clienttime.append(time.time())
- clienttime.append(defaultstate)
- print ("Starting UDP RELAY SERVER on %s port %s" % server_address)
- if clientamount < 1:
- print("QUITING DUE NO CLIENTS ALLOWED")
- return
- sock.bind(server_address)
- #licount=0 #this line is related to notepad++ python console
- strtoprint=""
- global prevpri
- global allclientsbroadcast
- while True:
- try:
- dispwaiting
- except NameError:
- dispwaiting=threading.Thread(target=listeshow)
- dispwaiting.start()
- if broadcastonlyactive or displayfake:
- dispdrop=threading.Thread(target=dropfollow)
- dispdrop.start()
- else:
- if broadcastonlyactive or displayfake:
- if not dispdrop.is_alive():
- dispdrop=threading.Thread(target=dropfollow)
- dispdrop.start()
- if not dispwaiting.is_alive():
- dispwaiting=threading.Thread(target=listeshow)
- dispwaiting.start()
- try:
- data, address = sock.recvfrom(data_payload)
- except Exception as e:
- console.writeError(str(e))
- strtoprint="%s%s\n" % (strtoprint,("[%03d] received %s bytes from %s" % (math.floor(time.time())%1000,len(data), address)))
- #print ("Data: %s" %data)
- ctest=[0,0,0,0]
- cindex=-1
- for x in clientused:
- if listen[x*2][0] == address[0]:
- ctest[0]=2
- if listen[x*2][1] == address[1]:
- ctest[1]=2
- if data[6:12] == listen[x*2+1]:
- ctest[2]=2
- if data and listen[x*2][0] == address[0] and listen[x*2][1] == address[1] and data[6:12] == listen[x*2+1]:
- ctest[0]=1
- ctest[1]=1
- ctest[2]=1
- clienttime[x*2]=time.time()
- clienttime[x*2+1]=False
- cindex=x
- break
- if cindex != -1:
- if data[:6] == macbroad:
- ctest[3]=1
- if allclientsbroadcast or cindex==0:
- for x in clientused:
- if x != cindex and (clienttime[x*2]+droptimeout > time.time() or not broadcastonlyactive):
- sent = mysendpacket(sock,data,listen[x*2])
- strtoprint="%s%s\n" % (strtoprint,("[%03d] broadcast %s bytes to %s" % (math.floor(time.time())%1000,sent, listen[x*2])))
- else:
- for x in clientused:
- if data[:6] == listen[x*2+1]:
- ctest[3]=2
- if x != cindex and (clienttime[x*2]+droptimeout > time.time() or not broadcastonlyactive):
- ctest[3]=1
- sent = mysendpacket(sock,data,listen[x*2])
- strtoprint="%s%s\n" % (strtoprint,("[%03d] send %s bytes to %s %s" % (math.floor(time.time())%1000,sent, listen[x*2],data[:6].hex())))
- break
- if not (ctest[0]==1 and ctest[1]==1 and ctest[2]==1 and ctest[3]==1):
- tmpstr=" %15s %05i %s %s %s\n" % (listen[cindex*2][0],listen[cindex*2][1],data[:6].hex(),data[6:12].hex(),data[12:].hex())
- tmpbyt=bytearray(tmpstr,"ascii")
- tmpbyt[0]=33 if (ctest[0] == 0) else (63 if ctest[0] == 2 else 32)
- tmpbyt[16]=33 if (ctest[0] == 0) else (63 if ctest[0] == 2 else 32)
- tmpbyt[18]=33 if (ctest[1] == 0) else (63 if ctest[1] == 2 else 32)
- tmpbyt[24]=33 if (ctest[1] == 0) else (63 if ctest[1] == 2 else 32)
- tmpbyt[26]=33 if (ctest[2] == 0) else (63 if ctest[2] == 2 else 32)
- tmpbyt[39]=33 if (ctest[2] == 0) else (63 if ctest[2] == 2 else 32)
- tmpbyt[41]=33 if (ctest[3] == 0) else (63 if ctest[3] == 2 else 32)
- tmpbyt[54]=33 if (ctest[3] == 0) else (63 if ctest[3] == 2 else 32)
- tmpstr=tmpbyt.decode("ascii")
- logifile.write(tmpstr)
- logifile.close()
- logifile.open(logfilename + logfileext, 'a')
- strtoprint="%s\n" % strtoprint
- if (prevpri + 0.3 < time.time()):
- prevpri=time.time()
- print(strtoprint,end='')
- strtoprint=""
- # licount+=1 #these 5 lines are related to notepad++ python console
- # if licount > 500:
- # licount=0
- # if console.editor.getCurrentPos() > 50000:
- # console.clear()
- #sys.stderr = console # remove first "#" to make standard log visible to notepad++ python console
- #sys.stdout = console # remove first "#" to make standard log visible to notepad++ python console
- try:
- echo_server(serverport)
- finally:
- pass
- # logifile.close()
- # if os.path.getsize(logfilename + logfileext) == 0:
- # os.remove(logfilename + logfileext)
Advertisement
Add Comment
Please, Sign In to add comment