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