mirror of
https://github.com/Oibaf66/frodo-wii.git
synced 2024-11-22 19:39:24 +01:00
lots of very broken network stuff
This commit is contained in:
parent
138854cc88
commit
b714e699fb
@ -68,6 +68,11 @@ Network::Network(int sock, bool is_master)
|
|||||||
|
|
||||||
/* Assume black screen */
|
/* Assume black screen */
|
||||||
memset(this->screen, 0, DISPLAY_X * DISPLAY_Y);
|
memset(this->screen, 0, DISPLAY_X * DISPLAY_Y);
|
||||||
|
|
||||||
|
/* Peer addresses */
|
||||||
|
memset(&this->private_addr, 0, sizeof(struct sockaddr_in));
|
||||||
|
memset(&this->public_addr, 0, sizeof(struct sockaddr_in));
|
||||||
|
this->connection_addr = &this->public_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Network::~Network()
|
Network::~Network()
|
||||||
@ -487,15 +492,17 @@ bool Network::ReceiveUpdate()
|
|||||||
bool out;
|
bool out;
|
||||||
|
|
||||||
memset(&tv, 0, sizeof(tv));
|
memset(&tv, 0, sizeof(tv));
|
||||||
out = this->ReceiveUpdate(this->ud, &tv);
|
out = this->ReceiveUpdate(this->ud, NETWORK_UPDATE_SIZE, &tv);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Network::ReceiveUpdate(NetworkUpdate *dst, struct timeval *tv)
|
bool Network::ReceiveUpdate(NetworkUpdate *dst, size_t total_sz,
|
||||||
|
struct timeval *tv)
|
||||||
{
|
{
|
||||||
Uint8 *pp = (Uint8*)dst;
|
Uint8 *pp = (Uint8*)dst;
|
||||||
NetworkUpdate *p;
|
NetworkUpdate *p;
|
||||||
|
size_t sz_left = total_sz;
|
||||||
|
|
||||||
if (this->Select(this->sock, tv) == false)
|
if (this->Select(this->sock, tv) == false)
|
||||||
return false;
|
return false;
|
||||||
@ -503,28 +510,25 @@ bool Network::ReceiveUpdate(NetworkUpdate *dst, struct timeval *tv)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
p = (NetworkUpdate*)pp;
|
p = (NetworkUpdate*)pp;
|
||||||
|
size_t actual_sz;
|
||||||
|
|
||||||
/* Receive the header */
|
if (sz_left <= 0)
|
||||||
if (this->ReceiveData((void*)p, this->sock, sizeof(NetworkUpdate)) == false)
|
return false;
|
||||||
|
|
||||||
|
/* Receive the header */
|
||||||
|
actual_sz = this->ReceiveFrom(pp, this->sock,
|
||||||
|
sz_left, this->connection_addr);
|
||||||
|
if (actual_sz < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pp = pp + sizeof(NetworkUpdate);
|
|
||||||
/* Drop if the magic is wrong */
|
/* Drop if the magic is wrong */
|
||||||
if (ntohs(p->magic) != FRODO_NETWORK_MAGIC)
|
if (ntohs(p->magic) != FRODO_NETWORK_MAGIC)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* And the rest of the update */
|
|
||||||
size_t sz = ntohl(p->size);
|
|
||||||
if (sz > sizeof(NetworkUpdate))
|
|
||||||
{
|
|
||||||
size_t sz_diff = sz - sizeof(NetworkUpdate);
|
|
||||||
|
|
||||||
if (this->ReceiveData((void*)pp, this->sock, sz_diff) == false)
|
|
||||||
return false;
|
|
||||||
pp = pp + sz_diff;
|
|
||||||
}
|
|
||||||
if (this->DeMarshalData(p) == false)
|
if (this->DeMarshalData(p) == false)
|
||||||
return false;
|
return false;
|
||||||
|
sz_left -= actual_sz;
|
||||||
|
pp = pp + actual_sz;
|
||||||
} while ( !(p->type == STOP) );
|
} while ( !(p->type == STOP) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -549,7 +553,7 @@ bool Network::SendUpdate()
|
|||||||
sz = this->GetNetworkUpdateSize();
|
sz = this->GetNetworkUpdateSize();
|
||||||
if (sz <= 0)
|
if (sz <= 0)
|
||||||
return false;
|
return false;
|
||||||
if (this->SendData((void*)src, this->sock, sz) == false)
|
if (this->SendTo((void*)src, this->sock, sz, this->connection_addr) < 0)
|
||||||
return false;
|
return false;
|
||||||
this->traffic += sz;
|
this->traffic += sz;
|
||||||
|
|
||||||
@ -564,6 +568,13 @@ void Network::AddNetworkUpdate(NetworkUpdate *update)
|
|||||||
this->cur_ud = (NetworkUpdate*)next;
|
this->cur_ud = (NetworkUpdate*)next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Network::MangleIp(uint8 *ip)
|
||||||
|
{
|
||||||
|
ip[0] = ~ip[0];
|
||||||
|
ip[1] = ~ip[1];
|
||||||
|
ip[2] = ~ip[2];
|
||||||
|
ip[3] = ~ip[3];
|
||||||
|
}
|
||||||
|
|
||||||
bool Network::MarshalData(NetworkUpdate *p)
|
bool Network::MarshalData(NetworkUpdate *p)
|
||||||
{
|
{
|
||||||
@ -578,6 +589,24 @@ bool Network::MarshalData(NetworkUpdate *p)
|
|||||||
case DISCONNECT:
|
case DISCONNECT:
|
||||||
case STOP:
|
case STOP:
|
||||||
break;
|
break;
|
||||||
|
case LIST_PEERS:
|
||||||
|
{
|
||||||
|
NetworkUpdateListPeers *lp = (NetworkUpdateListPeers *)p->data;
|
||||||
|
for (int i = 0; i < lp->n_peers; i++)
|
||||||
|
{
|
||||||
|
NetworkUpdatePeerInfo *peer = &lp->peers[i];
|
||||||
|
|
||||||
|
peer->key = htons(peer->key);
|
||||||
|
peer->private_port = htons(peer->private_port);
|
||||||
|
peer->public_port = htons(peer->public_port);
|
||||||
|
peer->is_master = htons(peer->is_master);
|
||||||
|
this->MangleIp(peer->private_ip);
|
||||||
|
this->MangleIp(peer->public_ip);
|
||||||
|
}
|
||||||
|
lp->n_peers = htonl(lp->n_peers);
|
||||||
|
this->MangleIp(lp->your_ip);
|
||||||
|
lp->your_port = htons(lp->your_port);
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
/* Unknown data... */
|
/* Unknown data... */
|
||||||
fprintf(stderr, "Got unknown data %d while marshalling. Something is wrong\n",
|
fprintf(stderr, "Got unknown data %d while marshalling. Something is wrong\n",
|
||||||
@ -630,6 +659,25 @@ bool Network::DeMarshalData(NetworkUpdate *p)
|
|||||||
case STOP:
|
case STOP:
|
||||||
/* Nothing to do, just bytes */
|
/* Nothing to do, just bytes */
|
||||||
break;
|
break;
|
||||||
|
case LIST_PEERS:
|
||||||
|
{
|
||||||
|
NetworkUpdateListPeers *lp = (NetworkUpdateListPeers *)p->data;
|
||||||
|
|
||||||
|
lp->n_peers = ntohl(lp->n_peers);
|
||||||
|
for (int i = 0; i < lp->n_peers; i++)
|
||||||
|
{
|
||||||
|
NetworkUpdatePeerInfo *peer = &lp->peers[i];
|
||||||
|
|
||||||
|
peer->key = ntohs(peer->key);
|
||||||
|
peer->private_port = ntohs(peer->private_port);
|
||||||
|
peer->public_port = ntohs(peer->public_port);
|
||||||
|
peer->is_master = ntohs(peer->is_master);
|
||||||
|
this->MangleIp(peer->private_ip);
|
||||||
|
this->MangleIp(peer->public_ip);
|
||||||
|
}
|
||||||
|
this->MangleIp(lp->your_ip);
|
||||||
|
lp->your_port = ntohs(lp->your_port);
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
/* Unknown data... */
|
/* Unknown data... */
|
||||||
return false;
|
return false;
|
||||||
@ -664,6 +712,15 @@ bool Network::DecodeUpdate(uint8 *screen, uint8 *js)
|
|||||||
*js = j->val;
|
*js = j->val;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case LIST_PEERS:
|
||||||
|
{
|
||||||
|
NetworkUpdateListPeers *lp = (NetworkUpdateListPeers *)p->data;
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case PING:
|
||||||
|
/* Send an ack */
|
||||||
|
break;
|
||||||
|
case ACK: /* Should never receive this */
|
||||||
case DISCONNECT:
|
case DISCONNECT:
|
||||||
out = false;
|
out = false;
|
||||||
break;
|
break;
|
||||||
|
@ -15,10 +15,16 @@
|
|||||||
#define NETWORK_SOUND_BUF_SIZE 1024
|
#define NETWORK_SOUND_BUF_SIZE 1024
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
STOP = 99,
|
/* Connection-related messages */
|
||||||
LIST_PEERS = 88,
|
HELLO = 99, /* Hello, broker */
|
||||||
DISCONNECT = 77,
|
LIST_PEERS = 98, /* List of peers */
|
||||||
PEER_INFO = 66,
|
PEER_CONNECT = 97, /* A peer wants to connect */
|
||||||
|
DISCONNECT = 96, /* Disconnect from a peer */
|
||||||
|
PING = 95, /* (broker) are you alive? */
|
||||||
|
ACK = 94, /* Answer to broker */
|
||||||
|
/* Non-data messages */
|
||||||
|
STOP = 55, /* End of this update sequence */
|
||||||
|
/* Data transfer of various kinds */
|
||||||
DISPLAY_UPDATE_RAW = 1,
|
DISPLAY_UPDATE_RAW = 1,
|
||||||
DISPLAY_UPDATE_RLE = 2,
|
DISPLAY_UPDATE_RLE = 2,
|
||||||
DISPLAY_UPDATE_DIFF= 3,
|
DISPLAY_UPDATE_DIFF= 3,
|
||||||
@ -36,20 +42,57 @@ struct NetworkUpdate
|
|||||||
uint32 size;
|
uint32 size;
|
||||||
|
|
||||||
/* The rest is just data of some type */
|
/* The rest is just data of some type */
|
||||||
Uint8 data[];
|
uint8 data[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NetworkUpdateDisplay
|
struct NetworkUpdateDisplay
|
||||||
{
|
{
|
||||||
Uint8 square;
|
uint8 square;
|
||||||
Uint8 data[];
|
uint8 data[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NetworkUpdateJoystick
|
struct NetworkUpdateJoystick
|
||||||
{
|
{
|
||||||
Uint8 val;
|
uint8 val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NetworkUpdatePingAck
|
||||||
|
{
|
||||||
|
uint8 seq;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sent by the third-party broker server when someone wants to connect
|
||||||
|
* to this machine.
|
||||||
|
*
|
||||||
|
* See http://www.brynosaurus.com/pub/net/p2pnat/ for how the UDP hole
|
||||||
|
* punching actually works.
|
||||||
|
*/
|
||||||
|
struct NetworkUpdatePeerInfo
|
||||||
|
{
|
||||||
|
uint16 private_port;
|
||||||
|
uint16 public_port;
|
||||||
|
|
||||||
|
uint8 private_ip[4]; /* Wii isn't ipv6 capable anyway AFAIK */
|
||||||
|
uint8 public_ip[4];
|
||||||
|
|
||||||
|
uint16 key; /* Random value to separate same names */
|
||||||
|
uint16 is_master;
|
||||||
|
uint8 name[32]; /* "SIMON", "LINDA" etc */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NetworkUpdateListPeers
|
||||||
|
{
|
||||||
|
uint32 n_peers;
|
||||||
|
uint8 your_ip[4];
|
||||||
|
uint16 your_port;
|
||||||
|
uint8 d[2]; /* Pad to 4 bytes */
|
||||||
|
|
||||||
|
/* Followed by the actual peers */
|
||||||
|
NetworkUpdatePeerInfo peers[];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static inline NetworkUpdate *InitNetworkUpdate(NetworkUpdate *ud, uint16 type, uint32 size)
|
static inline NetworkUpdate *InitNetworkUpdate(NetworkUpdate *ud, uint16 type, uint32 size)
|
||||||
{
|
{
|
||||||
ud->magic = FRODO_NETWORK_MAGIC;
|
ud->magic = FRODO_NETWORK_MAGIC;
|
||||||
@ -73,7 +116,7 @@ public:
|
|||||||
void EncodeJoystickUpdate(Uint8 v);
|
void EncodeJoystickUpdate(Uint8 v);
|
||||||
|
|
||||||
|
|
||||||
bool DecodeUpdate(uint8 *screen, uint8 *js = NULL);
|
bool DecodeUpdate(uint8 *screen, uint8 *js);
|
||||||
|
|
||||||
void ResetNetworkUpdate(void);
|
void ResetNetworkUpdate(void);
|
||||||
|
|
||||||
@ -195,14 +238,23 @@ protected:
|
|||||||
bool DecodeDisplayRaw(Uint8 *screen, struct NetworkUpdate *src,
|
bool DecodeDisplayRaw(Uint8 *screen, struct NetworkUpdate *src,
|
||||||
int x, int y);
|
int x, int y);
|
||||||
|
|
||||||
bool ReceiveUpdate(NetworkUpdate *dst, struct timeval *tv);
|
bool ReceiveUpdate(NetworkUpdate *dst, size_t sz, struct timeval *tv);
|
||||||
|
|
||||||
bool ReceiveData(void *dst, int sock, size_t sz);
|
bool ReceiveData(void *dst, int sock, size_t sz);
|
||||||
|
|
||||||
|
/* Simple wrapper around our friend recvfrom */
|
||||||
|
ssize_t ReceiveFrom(void *dst, int sock, size_t sz,
|
||||||
|
struct sockaddr_in *from);
|
||||||
|
|
||||||
|
ssize_t SendTo(void *src, int sock, size_t sz,
|
||||||
|
struct sockaddr_in *to);
|
||||||
|
|
||||||
bool SendData(void *src, int sock, size_t sz);
|
bool SendData(void *src, int sock, size_t sz);
|
||||||
|
|
||||||
virtual bool Select(int sock, struct timeval *tv);
|
virtual bool Select(int sock, struct timeval *tv);
|
||||||
|
|
||||||
|
void MangleIp(uint8 *ip);
|
||||||
|
|
||||||
bool MarshalData(NetworkUpdate *ud);
|
bool MarshalData(NetworkUpdate *ud);
|
||||||
|
|
||||||
bool MarshalAllData(NetworkUpdate *p);
|
bool MarshalAllData(NetworkUpdate *p);
|
||||||
@ -236,6 +288,10 @@ protected:
|
|||||||
/* Connection to the peer */
|
/* Connection to the peer */
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
|
struct sockaddr_in private_addr;
|
||||||
|
struct sockaddr_in public_addr;
|
||||||
|
struct sockaddr_in *connection_addr; /* Points to either of the above */
|
||||||
|
|
||||||
/* Listener-related */
|
/* Listener-related */
|
||||||
static int listen_sock;
|
static int listen_sock;
|
||||||
|
|
||||||
|
@ -174,6 +174,22 @@ bool Network::ReceiveData(void *dst, int sock, size_t sz)
|
|||||||
return sz > 0;
|
return sz > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t Network::ReceiveFrom(void *dst, int sock, size_t sz,
|
||||||
|
struct sockaddr_in *from)
|
||||||
|
{
|
||||||
|
socklen_t from_sz = from ? sizeof(struct sockaddr_in) : 0;
|
||||||
|
|
||||||
|
return recvfrom(sock, dst, sz, 0, (struct sockaddr*)from, &from_sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t Network::SendTo(void *src, int sock, size_t sz, struct sockaddr_in *to)
|
||||||
|
{
|
||||||
|
socklen_t to_sz = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
|
assert(to);
|
||||||
|
return sendto(sock, src, sz, 0, (struct sockaddr*)to, to_sz);
|
||||||
|
}
|
||||||
|
|
||||||
bool Network::SendData(void *src, int sock, size_t sz)
|
bool Network::SendData(void *src, int sock, size_t sz)
|
||||||
{
|
{
|
||||||
size_t sent_sz = 0;
|
size_t sent_sz = 0;
|
||||||
|
160
Src/network-broker/main.py
Normal file
160
Src/network-broker/main.py
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import socket
|
||||||
|
import SocketServer
|
||||||
|
import struct
|
||||||
|
|
||||||
|
FRODO_NETWORK_MAGIC = 0x1976
|
||||||
|
|
||||||
|
HELLO = 99
|
||||||
|
LIST_PEERS = 98
|
||||||
|
PEER_CONNECT = 97
|
||||||
|
DISCONNECT = 96
|
||||||
|
PING = 95
|
||||||
|
ACK = 94
|
||||||
|
STOP = 55
|
||||||
|
|
||||||
|
# Some of the Frodo network packets. There are more packets, but these
|
||||||
|
# are not interesting to the broker (and shouldn't be sent there either!)
|
||||||
|
packet_class_by_type = {
|
||||||
|
HELLO : HelloPacket,
|
||||||
|
LIST_PEERS : ListPeersPacket,
|
||||||
|
PEER_CONNECT : ListPeersPacket,
|
||||||
|
DISCONNECT : DisconnectPacket,
|
||||||
|
|
||||||
|
PING : PingPacket,
|
||||||
|
ACK : PingPacket, # Ping and ack are the same
|
||||||
|
|
||||||
|
STOP : StopPacket,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Packet:
|
||||||
|
def __init__(self, data):
|
||||||
|
"""Create a new packet from raw data. Data should always be in network
|
||||||
|
byte order"""
|
||||||
|
self.magic = struct.unpack(">H", data, offset = 0)[0]
|
||||||
|
self.type = struct.unpack(">H", data, offset = 2)[0]
|
||||||
|
self.size = struct.unpack(">L", data, offset = 4)[0]
|
||||||
|
|
||||||
|
def __init__(self, magic, type, size):
|
||||||
|
"""Create a new packet"""
|
||||||
|
self.magic = magic
|
||||||
|
self.type = type
|
||||||
|
self.size = size
|
||||||
|
|
||||||
|
def get_magic(self):
|
||||||
|
return self.magic
|
||||||
|
|
||||||
|
def get_type(self):
|
||||||
|
return self.type
|
||||||
|
|
||||||
|
def get_size(self):
|
||||||
|
return self.size
|
||||||
|
|
||||||
|
def marshal(self):
|
||||||
|
return struct.pack(">HHL", self.magic, self.type, self.size)
|
||||||
|
|
||||||
|
class PingPacket(Packet):
|
||||||
|
def __init__(self, seq):
|
||||||
|
Packet.__init__(self, FRODO_NETWORK_MAGIC, TYPE_PING, 9)
|
||||||
|
self.seq = seq
|
||||||
|
|
||||||
|
def get_seq(self):
|
||||||
|
return self.seq
|
||||||
|
|
||||||
|
def marshal(self):
|
||||||
|
return Packet.marshal(self) + struct.pack(">B", self.seq)
|
||||||
|
|
||||||
|
class PeerInfo:
|
||||||
|
def __init__(self, data):
|
||||||
|
self.private_port = struct.unpack(">H", data, offset = 0)[0]
|
||||||
|
self.public_port = struct.unpack(">H", data, offset = 2)[0]
|
||||||
|
self.private_ip = self.mangle_ip(struct.unpack(">BBBB", data, offset = 4))
|
||||||
|
self.public_ip = self.mangle_ip(struct.unpack(">BBBB", data, offset = 8))
|
||||||
|
self.key = struct.unpack(">H", data, offset = 12)[0]
|
||||||
|
self.is_master = struct.unpack(">H", data, offset = 16)[0]
|
||||||
|
self.name = struct.unpack("32s", data, offset = 20)
|
||||||
|
self.name[31] = 0
|
||||||
|
|
||||||
|
def set_public_address(ip, port):
|
||||||
|
self.public_ip = ip
|
||||||
|
self.public_port = port
|
||||||
|
|
||||||
|
def mangle_ip(self, ip):
|
||||||
|
ip[0] = ~int(ip[0])
|
||||||
|
ip[1] = ~int(ip[1])
|
||||||
|
ip[2] = ~int(ip[2])
|
||||||
|
ip[3] = ~int(ip[3])
|
||||||
|
|
||||||
|
def marshal(self):
|
||||||
|
priv_ip = self.mangle_ip(self.private_ip)
|
||||||
|
pub_ip = self.mangle_ip(self.public_ip)
|
||||||
|
return struct.pack(">HH4B4BHH32s",
|
||||||
|
self.private_port, self.public_port, priv_ip, pub_ip,
|
||||||
|
self.key, self.is_master, self.name)
|
||||||
|
|
||||||
|
class HelloPacket(Packet):
|
||||||
|
def __init__(self, data):
|
||||||
|
Packet.__init__(self, data)
|
||||||
|
|
||||||
|
self.peer_info = PeerInfo(data[8:])
|
||||||
|
|
||||||
|
def marshal(self):
|
||||||
|
return Packet.marshal(self) + self.peer_info.marshal()
|
||||||
|
|
||||||
|
class Peer:
|
||||||
|
def __init__(self, key, srv):
|
||||||
|
self.hash_key = key
|
||||||
|
self.srv = srv
|
||||||
|
|
||||||
|
def get_hash_key(self):
|
||||||
|
return self.hash_key
|
||||||
|
|
||||||
|
def handle_packet(self, data):
|
||||||
|
raw = Packet(data)
|
||||||
|
pkg_cls = packet_class_by_type[raw.get_type()]
|
||||||
|
pkg = pkg_cls(data)
|
||||||
|
|
||||||
|
if pkg.type == ACK:
|
||||||
|
pass
|
||||||
|
elif pkg.type == HELLO:
|
||||||
|
pass
|
||||||
|
elif pkg.type == PEER_CONNECT:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class BrokerPacketHandler(SocketServer.DatagramRequestHandler):
|
||||||
|
def handle(self):
|
||||||
|
srv = self.server
|
||||||
|
msg = self.rfile.read()
|
||||||
|
|
||||||
|
peer = srv.get_peer(self.client_addr)
|
||||||
|
try:
|
||||||
|
reply = peer.handle_packet()
|
||||||
|
except:
|
||||||
|
# Sends crap, let's remove it
|
||||||
|
srv.remove_peer(peer)
|
||||||
|
|
||||||
|
if reply != None:
|
||||||
|
self.wfile.write(reply)
|
||||||
|
|
||||||
|
class Broker(SocketServer.UDPServer):
|
||||||
|
|
||||||
|
def __init__(self, host, req_handler):
|
||||||
|
SocketServer.UDPServer.__init__(self, host, req_handler)
|
||||||
|
# Instead of setsockopt( ... REUSEADDR ... )
|
||||||
|
self.allow_reuse_address = True
|
||||||
|
self.peers = {}
|
||||||
|
|
||||||
|
def get_peer(self, key):
|
||||||
|
"Return the peer for a certain key, or a new one if it doesn't exist"
|
||||||
|
try:
|
||||||
|
peer = self.peers[key]
|
||||||
|
except KeyError, e:
|
||||||
|
peer = Peer(key, self)
|
||||||
|
return peer
|
||||||
|
|
||||||
|
def remove_peer(self, peer):
|
||||||
|
del self.peers[ peer.get_hash_key() ]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print "Starting Frodo network broker"
|
||||||
|
s = Broker( ("localhost", 46214), BrokerPacketHandler)
|
||||||
|
s.serve_forever()
|
Loading…
Reference in New Issue
Block a user