FOrwarding is working. Not well at the moment.
This commit is contained in:
parent
6e3c3ec0b2
commit
2a1c809731
88
node/conn.go
88
node/conn.go
@ -14,6 +14,7 @@ type connWriter struct {
|
||||
lock sync.Mutex
|
||||
localIP byte
|
||||
buf []byte
|
||||
buf2 []byte
|
||||
counters [256]uint64
|
||||
routing *routingTable
|
||||
}
|
||||
@ -23,6 +24,7 @@ func newConnWriter(conn *net.UDPConn, localIP byte, routing *routingTable) *conn
|
||||
UDPConn: conn,
|
||||
localIP: localIP,
|
||||
buf: make([]byte, bufferSize),
|
||||
buf2: make([]byte, bufferSize),
|
||||
routing: routing,
|
||||
}
|
||||
|
||||
@ -33,37 +35,76 @@ func newConnWriter(conn *net.UDPConn, localIP byte, routing *routingTable) *conn
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *connWriter) WriteTo(remoteIP, stream byte, data []byte) error {
|
||||
// TODO: Handle mediator.
|
||||
peer := w.routing.Get(remoteIP)
|
||||
if peer == nil || peer.Addr == nil {
|
||||
func (w *connWriter) WriteTo(remoteIP, stream byte, data []byte) {
|
||||
dstPeer := w.routing.Get(remoteIP)
|
||||
if dstPeer == nil {
|
||||
log.Printf("No peer: %d", remoteIP)
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
if stream == streamData && !peer.Up {
|
||||
if stream == streamData && !dstPeer.Up {
|
||||
log.Printf("Peer down: %d", remoteIP)
|
||||
}
|
||||
return w.WriteToPeer(peer, stream, data)
|
||||
return
|
||||
}
|
||||
|
||||
func (w *connWriter) WriteToPeer(peer *peer, stream byte, data []byte) error {
|
||||
var viaPeer *peer
|
||||
if dstPeer.Mediated {
|
||||
viaPeer = w.routing.mediator.Load()
|
||||
if viaPeer == nil || viaPeer.Addr == nil {
|
||||
log.Printf("Mediator not connected")
|
||||
return
|
||||
}
|
||||
} else if dstPeer.Addr == nil {
|
||||
log.Printf("Peer doesn't have address: %d", remoteIP)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteToPeer(dstPeer, viaPeer, stream, data)
|
||||
}
|
||||
|
||||
func (w *connWriter) WriteToPeer(dstPeer, viaPeer *peer, stream byte, data []byte) {
|
||||
w.lock.Lock()
|
||||
|
||||
remoteIP := peer.IP
|
||||
addr := dstPeer.Addr
|
||||
|
||||
h := header{
|
||||
Counter: atomic.AddUint64(&w.counters[remoteIP], 1),
|
||||
Counter: atomic.AddUint64(&w.counters[dstPeer.IP], 1),
|
||||
SourceIP: w.localIP,
|
||||
ViaIP: 0,
|
||||
DestIP: remoteIP,
|
||||
DestIP: dstPeer.IP,
|
||||
Stream: stream,
|
||||
}
|
||||
|
||||
buf := encryptPacket(&h, peer.SharedKey, data, w.buf)
|
||||
buf := encryptPacket(&h, dstPeer.SharedKey, data, w.buf)
|
||||
|
||||
_, err := w.WriteToUDPAddrPort(buf, *peer.Addr)
|
||||
if viaPeer != nil {
|
||||
h := header{
|
||||
Counter: atomic.AddUint64(&w.counters[viaPeer.IP], 1),
|
||||
SourceIP: w.localIP,
|
||||
DestIP: dstPeer.IP,
|
||||
Forward: 1,
|
||||
Stream: stream,
|
||||
}
|
||||
|
||||
buf = encryptPacket(&h, viaPeer.SharedKey, buf, w.buf2)
|
||||
addr = viaPeer.Addr
|
||||
}
|
||||
|
||||
if _, err := w.WriteToUDPAddrPort(buf, *addr); err != nil {
|
||||
log.Fatalf("Failed to write to UDP port: %v", err)
|
||||
}
|
||||
w.lock.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *connWriter) Forward(dstIP byte, packet []byte) {
|
||||
dstPeer := w.routing.Get(dstIP)
|
||||
if dstPeer == nil || dstPeer.Addr == nil {
|
||||
log.Printf("No peer: %d", dstIP)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := w.WriteToUDPAddrPort(packet, *dstPeer.Addr); err != nil {
|
||||
log.Fatalf("Failed to write to UDP port: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -89,38 +130,37 @@ func newConnReader(conn *net.UDPConn, localIP byte, routing *routingTable) *conn
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *connReader) Read(buf []byte) (remoteAddr netip.AddrPort, h header, data []byte, err error) {
|
||||
var n int
|
||||
func (r *connReader) Read(buf []byte) (remoteAddr netip.AddrPort, h header, data []byte) {
|
||||
var (
|
||||
n int
|
||||
err error
|
||||
)
|
||||
|
||||
for {
|
||||
n, remoteAddr, err = r.ReadFromUDPAddrPort(buf[:bufferSize])
|
||||
if err != nil {
|
||||
return
|
||||
log.Fatalf("Failed to read from UDP port: %v", err)
|
||||
}
|
||||
|
||||
data = buf[:n]
|
||||
|
||||
if n < headerSize {
|
||||
log.Printf("Dropping short packet: %d", n)
|
||||
continue // Packet it soo short.
|
||||
}
|
||||
|
||||
h.Parse(data)
|
||||
|
||||
if len(data) != headerSize+int(h.DataSize) {
|
||||
log.Printf("Malformed packet: %d != %d", len(data), headerSize+int(h.DataSize))
|
||||
continue
|
||||
continue // Invalid header.
|
||||
}
|
||||
|
||||
peer := r.routing.Get(h.SourceIP)
|
||||
if peer == nil {
|
||||
log.Printf("No peer: %d...", h.SourceIP)
|
||||
continue
|
||||
}
|
||||
|
||||
out, ok := decryptPacket(peer.SharedKey, data, r.buf)
|
||||
if !ok {
|
||||
log.Printf("Decrypt failed...")
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,8 @@ const (
|
||||
type header struct {
|
||||
Counter uint64 // Init with fasttime.Now() << 30 to ensure monotonic.
|
||||
SourceIP byte
|
||||
ViaIP byte
|
||||
DestIP byte
|
||||
Forward byte
|
||||
Stream byte // See stream* constants.
|
||||
DataSize uint16 // Data size following associated data.
|
||||
}
|
||||
@ -20,8 +20,8 @@ type header struct {
|
||||
func (hdr *header) Parse(nb []byte) {
|
||||
hdr.Counter = *(*uint64)(unsafe.Pointer(&nb[0]))
|
||||
hdr.SourceIP = nb[8]
|
||||
hdr.ViaIP = nb[9]
|
||||
hdr.DestIP = nb[10]
|
||||
hdr.DestIP = nb[9]
|
||||
hdr.Forward = nb[10]
|
||||
hdr.Stream = nb[11]
|
||||
hdr.DataSize = *(*uint16)(unsafe.Pointer(&nb[12]))
|
||||
}
|
||||
@ -29,8 +29,8 @@ func (hdr *header) Parse(nb []byte) {
|
||||
func (hdr header) Marshal(buf []byte) {
|
||||
*(*uint64)(unsafe.Pointer(&buf[0])) = hdr.Counter
|
||||
buf[8] = hdr.SourceIP
|
||||
buf[9] = hdr.ViaIP
|
||||
buf[10] = hdr.DestIP
|
||||
buf[9] = hdr.DestIP
|
||||
buf[10] = hdr.Forward
|
||||
buf[11] = hdr.Stream
|
||||
*(*uint16)(unsafe.Pointer(&buf[12])) = hdr.DataSize
|
||||
}
|
||||
|
16
node/main.go
16
node/main.go
@ -138,9 +138,11 @@ func nodeConnReader(r *connReader, w *connWriter, iface io.ReadWriteCloser, rout
|
||||
)
|
||||
|
||||
for {
|
||||
remoteAddr, h, data, err = r.Read(buf)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read from UDP connection: %v", err)
|
||||
remoteAddr, h, data = r.Read(buf)
|
||||
|
||||
if h.Forward != 0 {
|
||||
w.Forward(h.DestIP, data)
|
||||
continue
|
||||
}
|
||||
|
||||
switch h.Stream {
|
||||
@ -178,13 +180,9 @@ func nodeIFaceReader(w *connWriter, iface io.ReadWriteCloser, router *router) {
|
||||
}
|
||||
|
||||
if remoteIP == w.localIP {
|
||||
//log.Printf("Incoming packet for self: %x", packet)
|
||||
//iface.Write(packet)
|
||||
continue
|
||||
continue // Don't write to self.
|
||||
}
|
||||
|
||||
if err := w.WriteTo(remoteIP, streamData, packet); err != nil {
|
||||
log.Fatalf("Failed to write to network: %v", err)
|
||||
}
|
||||
w.WriteTo(remoteIP, streamData, packet)
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ import (
|
||||
|
||||
type peer struct {
|
||||
Up bool // No data will be sent to peers that are down.
|
||||
Mediator bool
|
||||
Mediated bool
|
||||
IP byte
|
||||
Addr *netip.AddrPort // If we have direct connection, otherwise use mediator.
|
||||
SharedKey []byte
|
||||
@ -49,8 +51,8 @@ func (r *routingTable) Set(ip byte, p *peer) {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type router struct {
|
||||
netName string
|
||||
*routingTable
|
||||
netName string
|
||||
peerSupers [256]*peerSupervisor
|
||||
}
|
||||
|
||||
@ -68,7 +70,7 @@ func newRouter(netName string, conf m.PeerConfig, routingData *routingTable, w *
|
||||
r.routingTable)
|
||||
}
|
||||
|
||||
// TODO: Handle Mediator
|
||||
go r.selectMediator()
|
||||
go r.pollHub(conf)
|
||||
|
||||
return r
|
||||
@ -111,7 +113,6 @@ func (r *router) pollHub(conf m.PeerConfig) {
|
||||
}
|
||||
req.SetBasicAuth("", conf.APIKey)
|
||||
|
||||
// TODO: Before we start polling, load state from the file system.
|
||||
state, err := loadNetworkState(r.netName)
|
||||
if err != nil {
|
||||
log.Printf("Failed to load network state: %v", err)
|
||||
@ -161,3 +162,25 @@ func (r *router) applyNetworkState(conf m.PeerConfig, state m.NetworkState) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func (r *router) selectMediator() {
|
||||
for range time.Tick(8 * time.Second) {
|
||||
current := r.mediator.Load()
|
||||
if current != nil && current.Up {
|
||||
continue
|
||||
}
|
||||
|
||||
for i := range r.table {
|
||||
peer := r.table[i].Load()
|
||||
if peer != nil && peer.Up && peer.Mediator {
|
||||
log.Printf("Got mediator: %v", *peer)
|
||||
r.mediator.Store(peer)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
r.mediator.Store(nil)
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ type peerSupervisor struct {
|
||||
version int64 // Ony accessed in HandlePeerUpdate.
|
||||
peer *m.Peer
|
||||
remoteAddrPort *netip.AddrPort
|
||||
mediated bool
|
||||
sharedKey []byte
|
||||
|
||||
// Used by our state functions.
|
||||
@ -94,7 +95,6 @@ func (s *peerSupervisor) HandlePeerUpdate(p *m.Peer) {
|
||||
if p.Version == s.version {
|
||||
return
|
||||
}
|
||||
s.logf("New peer version: %d", p.Version)
|
||||
s.version = p.Version
|
||||
} else {
|
||||
s.version = 0
|
||||
@ -154,6 +154,8 @@ func (s *peerSupervisor) stateSelectRole() stateFunc {
|
||||
s.updateRoutingTable(false)
|
||||
|
||||
if s.remoteAddrPort != nil {
|
||||
s.mediated = false
|
||||
|
||||
// If both remote and local are public, one side acts as client, and one
|
||||
// side as server.
|
||||
if s.localPublic && s.localIP < s.peer.PeerIP {
|
||||
@ -164,6 +166,7 @@ func (s *peerSupervisor) stateSelectRole() stateFunc {
|
||||
|
||||
// We're public, remote is not => can only wait for connection
|
||||
if s.localPublic {
|
||||
s.mediated = false
|
||||
return s.stateAccept
|
||||
}
|
||||
|
||||
@ -277,8 +280,18 @@ func (s *peerSupervisor) stateConnected() stateFunc {
|
||||
|
||||
func (s *peerSupervisor) stateMediated() stateFunc {
|
||||
s.logf("STATE: Mediated")
|
||||
// TODO
|
||||
select {}
|
||||
s.mediated = true
|
||||
s.updateRoutingTable(true)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.packets:
|
||||
// Drop.
|
||||
case s.peer = <-s.peerUpdates:
|
||||
s.logf("New peer: %v", s.peer)
|
||||
return s.stateInit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -290,6 +303,8 @@ func (s *peerSupervisor) clearRoutingTable() {
|
||||
func (s *peerSupervisor) updateRoutingTable(up bool) {
|
||||
s.table.Set(s.remoteIP, &peer{
|
||||
Up: up,
|
||||
Mediator: s.peer.Mediator,
|
||||
Mediated: s.mediated,
|
||||
IP: s.remoteIP,
|
||||
Addr: s.remoteAddrPort,
|
||||
SharedKey: s.sharedKey,
|
||||
|
Loading…
x
Reference in New Issue
Block a user