wip
This commit is contained in:
parent
08dc79283e
commit
e1a5f50e1a
@ -1,40 +1,44 @@
|
|||||||
package peer
|
package peer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
type connReader struct {
|
type connReader struct {
|
||||||
conn udpReader
|
// Input
|
||||||
iface ifWriter
|
readFromUDPAddrPort func([]byte) (int, netip.AddrPort, error)
|
||||||
sender encryptedPacketSender
|
|
||||||
super controlMsgHandler
|
// Output
|
||||||
|
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error)
|
||||||
|
iface io.Writer
|
||||||
|
handleControlMsg func(fromIP byte, pkt any)
|
||||||
|
|
||||||
localIP byte
|
localIP byte
|
||||||
peers [256]*atomic.Pointer[remotePeer]
|
rt *atomic.Pointer[routingTable]
|
||||||
|
|
||||||
buf []byte
|
buf []byte
|
||||||
decBuf []byte
|
decBuf []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConnReader(
|
func newConnReader(
|
||||||
conn udpReader,
|
readFromUDPAddrPort func([]byte) (int, netip.AddrPort, error),
|
||||||
ifWriter ifWriter,
|
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error),
|
||||||
sender encryptedPacketSender,
|
iface io.Writer,
|
||||||
super controlMsgHandler,
|
handleControlMsg func(fromIP byte, pkt any),
|
||||||
localIP byte,
|
rt *atomic.Pointer[routingTable],
|
||||||
peers [256]*atomic.Pointer[remotePeer],
|
|
||||||
) *connReader {
|
) *connReader {
|
||||||
return &connReader{
|
return &connReader{
|
||||||
conn: conn,
|
readFromUDPAddrPort: readFromUDPAddrPort,
|
||||||
iface: ifWriter,
|
writeToUDPAddrPort: writeToUDPAddrPort,
|
||||||
sender: sender,
|
iface: iface,
|
||||||
super: super,
|
handleControlMsg: handleControlMsg,
|
||||||
localIP: localIP,
|
localIP: rt.Load().LocalIP,
|
||||||
peers: peers,
|
rt: rt,
|
||||||
buf: make([]byte, bufferSize),
|
buf: newBuf(),
|
||||||
decBuf: make([]byte, bufferSize),
|
decBuf: newBuf(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,13 +48,11 @@ func (r *connReader) Run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *connReader) logf(s string, args ...any) {
|
|
||||||
log.Printf("[ConnReader] "+s, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *connReader) handleNextPacket() {
|
func (r *connReader) handleNextPacket() {
|
||||||
buf := r.buf[:bufferSize]
|
buf := r.buf[:bufferSize]
|
||||||
n, remoteAddr, err := r.conn.ReadFromUDPAddrPort(buf)
|
log.Printf("Getting next packet...")
|
||||||
|
n, remoteAddr, err := r.readFromUDPAddrPort(buf)
|
||||||
|
log.Printf("Packet from %v...", remoteAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to read from UDP port: %v", err)
|
log.Fatalf("Failed to read from UDP port: %v", err)
|
||||||
}
|
}
|
||||||
@ -64,23 +66,22 @@ func (r *connReader) handleNextPacket() {
|
|||||||
buf = buf[:n]
|
buf = buf[:n]
|
||||||
h := parseHeader(buf)
|
h := parseHeader(buf)
|
||||||
|
|
||||||
peer := r.peers[h.SourceIP].Load()
|
rt := r.rt.Load()
|
||||||
|
peer := rt.Peers[h.SourceIP]
|
||||||
|
|
||||||
switch h.StreamID {
|
switch h.StreamID {
|
||||||
case controlStreamID:
|
case controlStreamID:
|
||||||
r.handleControlPacket(peer, remoteAddr, h, buf)
|
r.handleControlPacket(remoteAddr, peer, h, buf)
|
||||||
|
|
||||||
case dataStreamID:
|
case dataStreamID:
|
||||||
r.handleDataPacket(peer, h, buf)
|
r.handleDataPacket(rt, peer, h, buf)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
r.logf("Unknown stream ID: %d", h.StreamID)
|
r.logf("Unknown stream ID: %d", h.StreamID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *connReader) handleControlPacket(
|
func (r *connReader) handleControlPacket(
|
||||||
peer *remotePeer,
|
remoteAddr netip.AddrPort,
|
||||||
addr netip.AddrPort,
|
peer remotePeer,
|
||||||
h header,
|
h header,
|
||||||
enc []byte,
|
enc []byte,
|
||||||
) {
|
) {
|
||||||
@ -93,22 +94,27 @@ func (r *connReader) handleControlPacket(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := decryptControlPacket(peer, addr, h, enc, r.decBuf)
|
msg, err := peer.DecryptControlPacket(remoteAddr, h, enc, r.decBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logf("Failed to decrypt control packet: %v", err)
|
r.logf("Failed to decrypt control packet: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
r.super.HandleControlMsg(msg)
|
r.handleControlMsg(h.SourceIP, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *connReader) handleDataPacket(peer *remotePeer, h header, enc []byte) {
|
func (r *connReader) handleDataPacket(
|
||||||
|
rt *routingTable,
|
||||||
|
peer remotePeer,
|
||||||
|
h header,
|
||||||
|
enc []byte,
|
||||||
|
) {
|
||||||
if !peer.Up {
|
if !peer.Up {
|
||||||
r.logf("Not connected (recv).")
|
r.logf("Not connected (recv).")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := decryptDataPacket(peer, h, enc, r.decBuf)
|
data, err := peer.DecryptDataPacket(h, enc, r.decBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logf("Failed to decrypt data packet: %v", err)
|
r.logf("Failed to decrypt data packet: %v", err)
|
||||||
return
|
return
|
||||||
@ -121,11 +127,15 @@ func (r *connReader) handleDataPacket(peer *remotePeer, h header, enc []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
destPeer := r.peers[h.DestIP].Load()
|
relay, ok := rt.GetRelay()
|
||||||
if !destPeer.Up {
|
if !ok {
|
||||||
r.logf("Not connected (relay): %d", destPeer.IP)
|
r.logf("Relay not available.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
r.sender.SendEncryptedDataPacket(data, destPeer)
|
r.writeToUDPAddrPort(data, relay.DirectAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *connReader) logf(format string, args ...any) {
|
||||||
|
log.Printf("[ConnReader] "+format, args...)
|
||||||
}
|
}
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
package peer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net/netip"
|
|
||||||
"sync/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ConnReader struct {
|
|
||||||
// Input
|
|
||||||
readFromUDPAddrPort func([]byte) (int, netip.AddrPort, error)
|
|
||||||
|
|
||||||
// Output
|
|
||||||
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error)
|
|
||||||
iface io.Writer
|
|
||||||
handleControlMsg func(fromIP byte, pkt any)
|
|
||||||
|
|
||||||
localIP byte
|
|
||||||
rt *atomic.Pointer[routingTable]
|
|
||||||
|
|
||||||
buf []byte
|
|
||||||
decBuf []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewConnReader(
|
|
||||||
readFromUDPAddrPort func([]byte) (int, netip.AddrPort, error),
|
|
||||||
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error),
|
|
||||||
iface io.Writer,
|
|
||||||
handleControlMsg func(fromIP byte, pkt any),
|
|
||||||
rt *atomic.Pointer[routingTable],
|
|
||||||
) *ConnReader {
|
|
||||||
return &ConnReader{
|
|
||||||
readFromUDPAddrPort: readFromUDPAddrPort,
|
|
||||||
writeToUDPAddrPort: writeToUDPAddrPort,
|
|
||||||
iface: iface,
|
|
||||||
handleControlMsg: handleControlMsg,
|
|
||||||
localIP: rt.Load().LocalIP,
|
|
||||||
rt: rt,
|
|
||||||
buf: newBuf(),
|
|
||||||
decBuf: newBuf(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ConnReader) Run() {
|
|
||||||
for {
|
|
||||||
r.handleNextPacket()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ConnReader) handleNextPacket() {
|
|
||||||
buf := r.buf[:bufferSize]
|
|
||||||
log.Printf("Getting next packet...")
|
|
||||||
n, remoteAddr, err := r.readFromUDPAddrPort(buf)
|
|
||||||
log.Printf("Packet from %v...", remoteAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to read from UDP port: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n < headerSize {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteAddr = netip.AddrPortFrom(remoteAddr.Addr().Unmap(), remoteAddr.Port())
|
|
||||||
|
|
||||||
buf = buf[:n]
|
|
||||||
h := parseHeader(buf)
|
|
||||||
|
|
||||||
rt := r.rt.Load()
|
|
||||||
peer := rt.Peers[h.SourceIP]
|
|
||||||
|
|
||||||
switch h.StreamID {
|
|
||||||
case controlStreamID:
|
|
||||||
r.handleControlPacket(remoteAddr, peer, h, buf)
|
|
||||||
case dataStreamID:
|
|
||||||
r.handleDataPacket(rt, peer, h, buf)
|
|
||||||
default:
|
|
||||||
r.logf("Unknown stream ID: %d", h.StreamID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ConnReader) handleControlPacket(
|
|
||||||
remoteAddr netip.AddrPort,
|
|
||||||
peer remotePeer,
|
|
||||||
h header,
|
|
||||||
enc []byte,
|
|
||||||
) {
|
|
||||||
if peer.ControlCipher == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if h.DestIP != r.localIP {
|
|
||||||
r.logf("Incorrect destination IP on control packet: %d", h.DestIP)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg, err := peer.DecryptControlPacket(remoteAddr, h, enc, r.decBuf)
|
|
||||||
if err != nil {
|
|
||||||
r.logf("Failed to decrypt control packet: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.handleControlMsg(h.SourceIP, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ConnReader) handleDataPacket(
|
|
||||||
rt *routingTable,
|
|
||||||
peer remotePeer,
|
|
||||||
h header,
|
|
||||||
enc []byte,
|
|
||||||
) {
|
|
||||||
if !peer.Up {
|
|
||||||
r.logf("Not connected (recv).")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := peer.DecryptDataPacket(h, enc, r.decBuf)
|
|
||||||
if err != nil {
|
|
||||||
r.logf("Failed to decrypt data packet: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if h.DestIP == r.localIP {
|
|
||||||
if _, err := r.iface.Write(data); err != nil {
|
|
||||||
log.Fatalf("Failed to write to interface: %v", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
relay, ok := rt.GetRelay()
|
|
||||||
if !ok {
|
|
||||||
r.logf("Relay not available.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.writeToUDPAddrPort(data, relay.DirectAddr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ConnReader) logf(format string, args ...any) {
|
|
||||||
log.Printf("[ConnReader] "+format, args...)
|
|
||||||
}
|
|
@ -37,7 +37,7 @@ func generateKeys() cryptoKeys {
|
|||||||
func encryptControlPacket(
|
func encryptControlPacket(
|
||||||
localIP byte,
|
localIP byte,
|
||||||
peer *remotePeer,
|
peer *remotePeer,
|
||||||
pkt Marshaller,
|
pkt marshaller,
|
||||||
tmp []byte,
|
tmp []byte,
|
||||||
out []byte,
|
out []byte,
|
||||||
) []byte {
|
) []byte {
|
||||||
|
@ -13,12 +13,12 @@ func newRoutePairForTesting() (*remotePeer, *remotePeer) {
|
|||||||
keys1 := generateKeys()
|
keys1 := generateKeys()
|
||||||
keys2 := generateKeys()
|
keys2 := generateKeys()
|
||||||
|
|
||||||
r1 := NewRemotePeer(1)
|
r1 := newRemotePeer(1)
|
||||||
r1.PubSignKey = keys1.PubSignKey
|
r1.PubSignKey = keys1.PubSignKey
|
||||||
r1.ControlCipher = newControlCipher(keys1.PrivKey, keys2.PubKey)
|
r1.ControlCipher = newControlCipher(keys1.PrivKey, keys2.PubKey)
|
||||||
r1.DataCipher = newDataCipher()
|
r1.DataCipher = newDataCipher()
|
||||||
|
|
||||||
r2 := NewRemotePeer(2)
|
r2 := newRemotePeer(2)
|
||||||
r2.PubSignKey = keys2.PubSignKey
|
r2.PubSignKey = keys2.PubSignKey
|
||||||
r2.ControlCipher = newControlCipher(keys2.PrivKey, keys1.PubKey)
|
r2.ControlCipher = newControlCipher(keys2.PrivKey, keys1.PubKey)
|
||||||
r2.DataCipher = r1.DataCipher
|
r2.DataCipher = r1.DataCipher
|
||||||
|
@ -27,3 +27,7 @@ var multicastAddr = net.UDPAddrFromAddrPort(netip.AddrPortFrom(
|
|||||||
func newBuf() []byte {
|
func newBuf() []byte {
|
||||||
return make([]byte, bufferSize)
|
return make([]byte, bufferSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type marshaller interface {
|
||||||
|
Marshal([]byte) []byte
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IFReader struct {
|
type ifReader struct {
|
||||||
iface io.Reader
|
iface io.Reader
|
||||||
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error)
|
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error)
|
||||||
rt *atomic.Pointer[routingTable]
|
rt *atomic.Pointer[routingTable]
|
||||||
@ -15,22 +15,22 @@ type IFReader struct {
|
|||||||
buf2 []byte
|
buf2 []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIFReader(
|
func newIFReader(
|
||||||
iface io.Reader,
|
iface io.Reader,
|
||||||
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error),
|
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error),
|
||||||
rt *atomic.Pointer[routingTable],
|
rt *atomic.Pointer[routingTable],
|
||||||
) *IFReader {
|
) *ifReader {
|
||||||
return &IFReader{iface, writeToUDPAddrPort, rt, newBuf(), newBuf()}
|
return &ifReader{iface, writeToUDPAddrPort, rt, newBuf(), newBuf()}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *IFReader) Run() {
|
func (r *ifReader) Run() {
|
||||||
packet := newBuf()
|
packet := newBuf()
|
||||||
for {
|
for {
|
||||||
r.handleNextPacket(packet)
|
r.handleNextPacket(packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *IFReader) handleNextPacket(packet []byte) {
|
func (r *ifReader) handleNextPacket(packet []byte) {
|
||||||
packet = r.readNextPacket(packet)
|
packet = r.readNextPacket(packet)
|
||||||
remoteIP, ok := r.parsePacket(packet)
|
remoteIP, ok := r.parsePacket(packet)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -60,7 +60,7 @@ func (r *IFReader) handleNextPacket(packet []byte) {
|
|||||||
r.writeToUDPAddrPort(enc, relay.DirectAddr)
|
r.writeToUDPAddrPort(enc, relay.DirectAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *IFReader) readNextPacket(buf []byte) []byte {
|
func (r *ifReader) readNextPacket(buf []byte) []byte {
|
||||||
n, err := r.iface.Read(buf[:cap(buf)])
|
n, err := r.iface.Read(buf[:cap(buf)])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to read from interface: %v", err)
|
log.Fatalf("Failed to read from interface: %v", err)
|
||||||
@ -69,7 +69,7 @@ func (r *IFReader) readNextPacket(buf []byte) []byte {
|
|||||||
return buf[:n]
|
return buf[:n]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *IFReader) parsePacket(buf []byte) (byte, bool) {
|
func (r *ifReader) parsePacket(buf []byte) (byte, bool) {
|
||||||
n := len(buf)
|
n := len(buf)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return 0, false
|
return 0, false
|
||||||
@ -98,6 +98,6 @@ func (r *IFReader) parsePacket(buf []byte) (byte, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*IFReader) logf(s string, args ...any) {
|
func (*ifReader) logf(s string, args ...any) {
|
||||||
log.Printf("[IFReader] "+s, args...)
|
log.Printf("[IFReader] "+s, args...)
|
||||||
}
|
}
|
@ -3,7 +3,6 @@ package peer
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -11,45 +10,6 @@ import (
|
|||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get next packet, returning packet, ip, and possible error.
|
|
||||||
func readNextPacket(iface io.ReadWriteCloser, buf []byte) ([]byte, byte, error) {
|
|
||||||
var (
|
|
||||||
version byte
|
|
||||||
ip byte
|
|
||||||
)
|
|
||||||
for {
|
|
||||||
n, err := iface.Read(buf[:cap(buf)])
|
|
||||||
if err != nil {
|
|
||||||
return nil, ip, err
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = buf[:n]
|
|
||||||
version = buf[0] >> 4
|
|
||||||
|
|
||||||
switch version {
|
|
||||||
case 4:
|
|
||||||
if n < 20 {
|
|
||||||
log.Printf("Short IPv4 packet: %d", len(buf))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ip = buf[19]
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
if len(buf) < 40 {
|
|
||||||
log.Printf("Short IPv6 packet: %d", len(buf))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ip = buf[39]
|
|
||||||
|
|
||||||
default:
|
|
||||||
log.Printf("Invalid IP packet version: %v", version)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf, ip, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func openInterface(network []byte, localIP byte, name string) (io.ReadWriteCloser, error) {
|
func openInterface(network []byte, localIP byte, name string) (io.ReadWriteCloser, error) {
|
||||||
if len(network) != 4 {
|
if len(network) != 4 {
|
||||||
return nil, fmt.Errorf("expected network to be 4 bytes, got %d", len(network))
|
return nil, fmt.Errorf("expected network to be 4 bytes, got %d", len(network))
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
package peer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"net/netip"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UDPConn interface {
|
|
||||||
ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error)
|
|
||||||
WriteToUDPAddrPort([]byte, netip.AddrPort) (int, error)
|
|
||||||
WriteToUDP([]byte, *net.UDPAddr) (int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ifWriter io.Writer
|
|
||||||
|
|
||||||
type udpReader interface {
|
|
||||||
ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type udpWriter interface {
|
|
||||||
WriteToUDPAddrPort([]byte, netip.AddrPort) (int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type mcUDPWriter interface {
|
|
||||||
WriteToUDP([]byte, *net.UDPAddr) (int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Marshaller interface {
|
|
||||||
Marshal([]byte) []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type dataPacketSender interface {
|
|
||||||
SendDataPacket(pkt []byte, peer *remotePeer)
|
|
||||||
RelayDataPacket(pkt []byte, peer, relay *remotePeer)
|
|
||||||
}
|
|
||||||
|
|
||||||
type controlPacketSender interface {
|
|
||||||
SendControlPacket(pkt Marshaller, peer *remotePeer)
|
|
||||||
RelayControlPacket(pkt Marshaller, peer, relay *remotePeer)
|
|
||||||
}
|
|
||||||
|
|
||||||
type encryptedPacketSender interface {
|
|
||||||
SendEncryptedDataPacket(pkt []byte, peer *remotePeer)
|
|
||||||
}
|
|
||||||
|
|
||||||
type controlMsgHandler interface {
|
|
||||||
HandleControlMsg(pkt any)
|
|
||||||
}
|
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Main() {
|
func Main() {
|
||||||
conf := Config{}
|
conf := peerConfig{}
|
||||||
|
|
||||||
flag.StringVar(&conf.NetName, "name", "", "[REQUIRED] The network name.")
|
flag.StringVar(&conf.NetName, "name", "", "[REQUIRED] The network name.")
|
||||||
flag.StringVar(&conf.HubAddress, "hub-address", "", "[REQUIRED] The hub address.")
|
flag.StringVar(&conf.HubAddress, "hub-address", "", "[REQUIRED] The hub address.")
|
||||||
@ -18,6 +18,6 @@ func Main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
peer := New(conf)
|
peer := newPeerMain(conf)
|
||||||
peer.Run()
|
peer.Run()
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
package peer
|
package peer
|
||||||
|
|
||||||
import (
|
/*
|
||||||
"log"
|
|
||||||
"sync/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
type mcReader struct {
|
type mcReader struct {
|
||||||
conn udpReader
|
conn udpReader
|
||||||
super controlMsgHandler
|
super controlMsgHandler
|
||||||
@ -55,3 +51,4 @@ func (r *mcReader) handleNextPacket() {
|
|||||||
SrcAddr: remoteAddr,
|
SrcAddr: remoteAddr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package peer
|
package peer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/nacl/sign"
|
"golang.org/x/crypto/nacl/sign"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,7 +32,9 @@ func verifyLocalDiscoveryPacket(pkt, buf []byte, pubSignKey []byte) bool {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
type mcWriter struct {
|
type mcWriter struct {
|
||||||
|
|
||||||
conn mcUDPWriter
|
conn mcUDPWriter
|
||||||
discoveryPacket []byte
|
discoveryPacket []byte
|
||||||
}
|
}
|
||||||
@ -50,4 +50,4 @@ func (w *mcWriter) SendLocalDiscovery() {
|
|||||||
if _, err := w.conn.WriteToUDP(w.discoveryPacket, multicastAddr); err != nil {
|
if _, err := w.conn.WriteToUDP(w.discoveryPacket, multicastAddr); err != nil {
|
||||||
log.Printf("[MCWriter] Failed to write multicast UDP packet: %v", err)
|
log.Printf("[MCWriter] Failed to write multicast UDP packet: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
package peer
|
package peer
|
||||||
|
|
||||||
import (
|
/*
|
||||||
"bytes"
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Testing that we can create and verify a local discovery packet.
|
// Testing that we can create and verify a local discovery packet.
|
||||||
@ -100,3 +95,4 @@ func TestMCWriter_SendLocalDiscovery(t *testing.T) {
|
|||||||
t.Fatal("Verification should succeed.")
|
t.Fatal("Verification should succeed.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
24
peer/peer.go
24
peer/peer.go
@ -15,21 +15,21 @@ import (
|
|||||||
"vppn/m"
|
"vppn/m"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Peer struct {
|
type peerMain struct {
|
||||||
ifReader *IFReader
|
ifReader *ifReader
|
||||||
connReader *ConnReader
|
connReader *connReader
|
||||||
iface io.Writer
|
iface io.Writer
|
||||||
hubPoller *hubPoller
|
hubPoller *hubPoller
|
||||||
super *Super
|
super *supervisor
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type peerConfig struct {
|
||||||
NetName string
|
NetName string
|
||||||
HubAddress string
|
HubAddress string
|
||||||
APIKey string
|
APIKey string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(conf Config) *Peer {
|
func newPeerMain(conf peerConfig) *peerMain {
|
||||||
config, err := loadPeerConfig(conf.NetName)
|
config, err := loadPeerConfig(conf.NetName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to load configuration: %v", err)
|
log.Printf("Failed to load configuration: %v", err)
|
||||||
@ -83,15 +83,15 @@ func New(conf Config) *Peer {
|
|||||||
rtPtr := &atomic.Pointer[routingTable]{}
|
rtPtr := &atomic.Pointer[routingTable]{}
|
||||||
rtPtr.Store(&rt)
|
rtPtr.Store(&rt)
|
||||||
|
|
||||||
ifReader := NewIFReader(iface, writeToUDPAddrPort, rtPtr)
|
ifReader := newIFReader(iface, writeToUDPAddrPort, rtPtr)
|
||||||
super := NewSuper(writeToUDPAddrPort, rtPtr, config.PrivKey)
|
super := newSupervisor(writeToUDPAddrPort, rtPtr, config.PrivKey)
|
||||||
connReader := NewConnReader(conn.ReadFromUDPAddrPort, writeToUDPAddrPort, iface, super.HandleControlMsg, rtPtr)
|
connReader := newConnReader(conn.ReadFromUDPAddrPort, writeToUDPAddrPort, iface, super.HandleControlMsg, rtPtr)
|
||||||
hubPoller, err := newHubPoller(config.PeerIP, conf.NetName, conf.HubAddress, conf.APIKey, super.HandleControlMsg)
|
hubPoller, err := newHubPoller(config.PeerIP, conf.NetName, conf.HubAddress, conf.APIKey, super.HandleControlMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to create hub poller: %v", err)
|
log.Fatalf("Failed to create hub poller: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Peer{
|
return &peerMain{
|
||||||
iface: iface,
|
iface: iface,
|
||||||
ifReader: ifReader,
|
ifReader: ifReader,
|
||||||
connReader: connReader,
|
connReader: connReader,
|
||||||
@ -100,14 +100,14 @@ func New(conf Config) *Peer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Peer) Run() {
|
func (p *peerMain) Run() {
|
||||||
go p.ifReader.Run()
|
go p.ifReader.Run()
|
||||||
go p.connReader.Run()
|
go p.connReader.Run()
|
||||||
p.super.Start()
|
p.super.Start()
|
||||||
p.hubPoller.Run()
|
p.hubPoller.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func initPeerWithHub(conf Config) {
|
func initPeerWithHub(conf peerConfig) {
|
||||||
keys := generateKeys()
|
keys := generateKeys()
|
||||||
|
|
||||||
initURL, err := url.Parse(conf.HubAddress)
|
initURL, err := url.Parse(conf.HubAddress)
|
||||||
|
@ -14,8 +14,8 @@ type P struct {
|
|||||||
RT *atomic.Pointer[routingTable]
|
RT *atomic.Pointer[routingTable]
|
||||||
Conn *TestUDPConn
|
Conn *TestUDPConn
|
||||||
IFace *TestIFace
|
IFace *TestIFace
|
||||||
ConnReader *ConnReader
|
ConnReader *connReader
|
||||||
IFReader *IFReader
|
IFReader *ifReader
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPeerForTesting(n *TestNetwork, ip byte, addr netip.AddrPort) P {
|
func NewPeerForTesting(n *TestNetwork, ip byte, addr netip.AddrPort) P {
|
||||||
|
@ -25,7 +25,7 @@ type peerState interface {
|
|||||||
type pState struct {
|
type pState struct {
|
||||||
// Output.
|
// Output.
|
||||||
publish func(remotePeer)
|
publish func(remotePeer)
|
||||||
sendControlPacket func(remotePeer, Marshaller)
|
sendControlPacket func(remotePeer, marshaller)
|
||||||
|
|
||||||
// Immutable data.
|
// Immutable data.
|
||||||
localIP byte
|
localIP byte
|
||||||
@ -124,7 +124,7 @@ func (s *pState) logf(format string, args ...any) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
func (s *pState) SendTo(pkt Marshaller, addr netip.AddrPort) {
|
func (s *pState) SendTo(pkt marshaller, addr netip.AddrPort) {
|
||||||
if !addr.IsValid() {
|
if !addr.IsValid() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ func (s *pState) SendTo(pkt Marshaller, addr netip.AddrPort) {
|
|||||||
s.Send(route, pkt)
|
s.Send(route, pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pState) Send(peer remotePeer, pkt Marshaller) {
|
func (s *pState) Send(peer remotePeer, pkt marshaller) {
|
||||||
if err := s.limiter.Limit(); err != nil {
|
if err := s.limiter.Limit(); err != nil {
|
||||||
s.logf("Rate limited.")
|
s.logf("Rate limited.")
|
||||||
return
|
return
|
||||||
|
@ -31,7 +31,7 @@ func NewPeerStateTestHarness() *PeerStateTestHarness {
|
|||||||
publish: func(rp remotePeer) {
|
publish: func(rp remotePeer) {
|
||||||
h.Published = rp
|
h.Published = rp
|
||||||
},
|
},
|
||||||
sendControlPacket: func(rp remotePeer, pkt Marshaller) {
|
sendControlPacket: func(rp remotePeer, pkt marshaller) {
|
||||||
h.Sent = append(h.Sent, PeerStateControlMsg{rp, pkt})
|
h.Sent = append(h.Sent, PeerStateControlMsg{rp, pkt})
|
||||||
},
|
},
|
||||||
localIP: 2,
|
localIP: 2,
|
||||||
|
@ -11,26 +11,26 @@ import (
|
|||||||
"git.crumpington.com/lib/go/ratelimiter"
|
"git.crumpington.com/lib/go/ratelimiter"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Super struct {
|
type supervisor struct {
|
||||||
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error)
|
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error)
|
||||||
staged routingTable
|
staged routingTable
|
||||||
shared *atomic.Pointer[routingTable]
|
shared *atomic.Pointer[routingTable]
|
||||||
peers [256]*PeerSuper
|
peers [256]*peerSuper
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
|
||||||
buf1 []byte
|
buf1 []byte
|
||||||
buf2 []byte
|
buf2 []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSuper(
|
func newSupervisor(
|
||||||
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error),
|
writeToUDPAddrPort func([]byte, netip.AddrPort) (int, error),
|
||||||
rt *atomic.Pointer[routingTable],
|
rt *atomic.Pointer[routingTable],
|
||||||
privKey []byte,
|
privKey []byte,
|
||||||
) *Super {
|
) *supervisor {
|
||||||
|
|
||||||
routes := rt.Load()
|
routes := rt.Load()
|
||||||
|
|
||||||
s := &Super{
|
s := &supervisor{
|
||||||
writeToUDPAddrPort: writeToUDPAddrPort,
|
writeToUDPAddrPort: writeToUDPAddrPort,
|
||||||
staged: *routes,
|
staged: *routes,
|
||||||
shared: rt,
|
shared: rt,
|
||||||
@ -55,23 +55,23 @@ func NewSuper(
|
|||||||
MaxWaitCount: 1,
|
MaxWaitCount: 1,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
s.peers[i] = NewPeerSuper(state)
|
s.peers[i] = newPeerSuper(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Super) Start() {
|
func (s *supervisor) Start() {
|
||||||
for i := range s.peers {
|
for i := range s.peers {
|
||||||
go s.peers[i].Run()
|
go s.peers[i].Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Super) HandleControlMsg(destIP byte, msg any) {
|
func (s *supervisor) HandleControlMsg(destIP byte, msg any) {
|
||||||
s.peers[destIP].HandleControlMsg(msg)
|
s.peers[destIP].HandleControlMsg(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Super) send(peer remotePeer, pkt Marshaller) {
|
func (s *supervisor) send(peer remotePeer, pkt marshaller) {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ func (s *Super) send(peer remotePeer, pkt Marshaller) {
|
|||||||
s.writeToUDPAddrPort(enc, relay.DirectAddr)
|
s.writeToUDPAddrPort(enc, relay.DirectAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Super) publish(rp remotePeer) {
|
func (s *supervisor) publish(rp remotePeer) {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ func (s *Super) publish(rp remotePeer) {
|
|||||||
s.shared.Store(©)
|
s.shared.Store(©)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Super) ensureRelay() {
|
func (s *supervisor) ensureRelay() {
|
||||||
if _, ok := s.staged.GetRelay(); ok {
|
if _, ok := s.staged.GetRelay(); ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -116,26 +116,26 @@ func (s *Super) ensureRelay() {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type PeerSuper struct {
|
type peerSuper struct {
|
||||||
messages chan any
|
messages chan any
|
||||||
state peerState
|
state peerState
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPeerSuper(state *pState) *PeerSuper {
|
func newPeerSuper(state *pState) *peerSuper {
|
||||||
return &PeerSuper{
|
return &peerSuper{
|
||||||
messages: make(chan any, 8),
|
messages: make(chan any, 8),
|
||||||
state: state.OnPeerUpdate(nil),
|
state: state.OnPeerUpdate(nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PeerSuper) HandleControlMsg(msg any) {
|
func (s *peerSuper) HandleControlMsg(msg any) {
|
||||||
select {
|
select {
|
||||||
case s.messages <- msg:
|
case s.messages <- msg:
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PeerSuper) Run() {
|
func (s *peerSuper) Run() {
|
||||||
go func() {
|
go func() {
|
||||||
// Randomize ping timers.
|
// Randomize ping timers.
|
||||||
time.Sleep(time.Duration(rand.Intn(4000)) * time.Millisecond)
|
time.Sleep(time.Duration(rand.Intn(4000)) * time.Millisecond)
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Remove
|
// TODO: Remove
|
||||||
func NewRemotePeer(ip byte) *remotePeer {
|
func newRemotePeer(ip byte) *remotePeer {
|
||||||
counter := uint64(time.Now().Unix()<<30 + 1)
|
counter := uint64(time.Now().Unix()<<30 + 1)
|
||||||
return &remotePeer{
|
return &remotePeer{
|
||||||
IP: ip,
|
IP: ip,
|
||||||
@ -58,7 +58,7 @@ func (p remotePeer) DecryptDataPacket(h header, enc, out []byte) ([]byte, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Peer must have a ControlCipher.
|
// Peer must have a ControlCipher.
|
||||||
func (p remotePeer) EncryptControlPacket(pkt Marshaller, tmp, out []byte) []byte {
|
func (p remotePeer) EncryptControlPacket(pkt marshaller, tmp, out []byte) []byte {
|
||||||
tmp = pkt.Marshal(tmp)
|
tmp = pkt.Marshal(tmp)
|
||||||
h := header{
|
h := header{
|
||||||
StreamID: controlStreamID,
|
StreamID: controlStreamID,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user