Last active
December 10, 2018 11:15
-
-
Save abendayan/5f5e09a8a3743d9ccfd3d4355a3a53b8 to your computer and use it in GitHub Desktop.
p2p
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
"""UDP hole punching client.""" | |
from twisted.internet.protocol import DatagramProtocol | |
from twisted.internet import reactor | |
import time | |
import sys | |
class ClientProtocol(DatagramProtocol): | |
""" | |
Client protocol implementation. | |
The clients registers with the rendezvous server. | |
The rendezvous server returns connection details for the other peer. | |
The client Initializes a connection with the other peer and sends a | |
message. | |
""" | |
def startProtocol(self): | |
"""Register with the rendezvous server.""" | |
self.server_connect = False | |
self.peer_init = False | |
self.peer_connect = False | |
self.peer_address = None | |
self.last_message = [] | |
self.transport.write(b'0', (sys.argv[1], int(sys.argv[2]))) | |
self.all_addresses = [] | |
def toAddress(self, data): | |
"""Return an IPv4 address tuple.""" | |
ip, port = data.split(':') | |
return (ip, int(port)) | |
def sendMessage(self, message): | |
self.wait_for_ack = True | |
for address in self.all_addresses: | |
self.last_message.append((message, address)) | |
self.transport.write(self.last_message) | |
def datagramReceived(self, datagram, host): | |
"""Handle incoming datagram messages.""" | |
if not self.server_connect: | |
self.server_connect = True | |
self.transport.write('ok', (sys.argv[1], int(sys.argv[2]))) | |
self.last_message.append(('ok', (sys.argv[1], int(sys.argv[2])))) | |
self.wait_for_ack = True | |
print 'Connected to server, waiting for peer...' | |
elif datagram.startswith('init'): | |
peer_address = self.toAddress(datagram.split('init ')[1]) | |
self.all_addresses.append(peer_address) | |
host = self.transport.getHost().host | |
port = self.transport.getHost().port | |
msg = 'Message from %s %d' % (host, port) | |
self.all_addresses.append(peer_address) | |
print msg | |
for address in self.all_addresses: | |
if address != peer_address: | |
self.transport.write(msg, address) | |
elif ':' in datagram: | |
self.peer_address = self.toAddress(datagram) | |
self.all_addresses.append(self.peer_address) | |
host = self.transport.getHost().host | |
port = self.transport.getHost().port | |
msg = 'init %s:%d' % (host, port) | |
self.transport.write(msg, self.peer_address) | |
self.last_message.append((msg, self.peer_address)) | |
print 'Sent init to %s:%d' % self.peer_address | |
else: | |
print 'Received:', datagram | |
if __name__ == '__main__': | |
if len(sys.argv) < 3: | |
print "Usage: ./client RENDEZVOUS_IP RENDEZVOUS_PORT" | |
sys.exit(1) | |
protocol = ClientProtocol() | |
t = reactor.listenUDP(0, protocol) | |
reactor.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from web3 import Web3 | |
from web3 import TestRPCProvider | |
from os import path | |
import json | |
import web3 | |
class ContractHandler: | |
def __init__(self): | |
self.web3 = Web3(web3.providers.rpc.HTTPProvider("http://bch63v-dns-reg1.westeurope.cloudapp.azure.com:8545")) | |
with open(str(path.join('.', 'contract.json')), 'r') as abi_definition: | |
self.abi = json.load(abi_definition) | |
self.contract_address ='0x4c9a6e78730de2e1af5461abb69345b503bb606605223e22492318e636144583' | |
self.contract = self.web3.eth.contract() | |
self.contract.abi = self.abi | |
self.contract.address = self.contract_address | |
if path.isfile("wallet.dat"): | |
self.wallet = web3.Account.privateKeyToAccount(open("wallet.dat", "rb").read()) | |
else: | |
self.wallet = web3.Account.create() | |
open("wallet.dat", "wb").write(self.wallet.privateKey) | |
print(self.wallet.address, self.wallet.privateKey) | |
print(self.contract) | |
# def unlock(self): | |
# self.web3.personal.unlockAccount(your_ethereum_account, | |
# your_ethereum_password) | |
contract = ContractHandler() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
"""UDP hole punching server.""" | |
from twisted.internet.protocol import DatagramProtocol | |
from twisted.internet import reactor | |
from itertools import combinations | |
import sys | |
class ServerProtocol(DatagramProtocol): | |
""" | |
Server protocol implementation. | |
Server listens for UDP messages. Once it receives a message it registers | |
this client for a peer link in the waiting list. | |
As soon as a second client connects, information about one client (public | |
IP address and port) is sent to the other and vice versa. | |
Those clients are now considered linked and removed from the waiting list. | |
""" | |
def __init__(self): | |
"""Initialize with empy address list.""" | |
self.addresses = [] | |
self.sitin = [] | |
def addressString(self, address): | |
"""Return a string representation of an address.""" | |
ip, port = address | |
return ':'.join([ip, str(port)]) | |
def datagramReceived(self, datagram, message): | |
"""Handle incoming datagram messages.""" | |
if datagram == b'0': | |
# New client | |
print 'Registration from %s:%d' % message | |
self.transport.write(b'ok', message) | |
self.addresses.append(message) | |
self.sitin.append(False) | |
if len(self.addresses) >= 2: | |
pairs_addresses = list(combinations(self.addresses, 2)) | |
for address in pairs_addresses: | |
print address | |
msg_0 = self.addressString(address[1]) | |
msg_1 = self.addressString(address[0]) | |
self.transport.write(msg_0, address[0]) | |
self.transport.write(msg_1, address[1]) | |
print 'Linked peers' | |
elif datagram == b'1': | |
# This client sent the command sit in | |
self.sitin[self.addresses.index((message[0], message[1]))] = True | |
if len(self.addresses) >= 2 and (sum(self.sitin) == len(self.addresses)): | |
pairs_addresses = list(combinations(self.addresses, 2)) | |
for address in pairs_addresses: | |
msg_0 = self.addressString(address[1]) | |
msg_1 = self.addressString(address[0]) | |
self.transport.write(msg_0, address[0]) | |
self.transport.write(msg_1, address[1]) | |
print 'Linked peers' | |
else: | |
print 'Message %s from %s:%d' % (datagram, message[0], message[1]) | |
if __name__ == '__main__': | |
if len(sys.argv) < 2: | |
print "Usage: ./server.py PORT" | |
sys.exit(1) | |
port = int(sys.argv[1]) | |
reactor.listenUDP(port, ServerProtocol()) | |
print 'Listening on *:%d' % (port) | |
reactor.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment