feat: add TODOs for path table persistence and improve packet handling logic in transport
This commit is contained in:
@@ -160,7 +160,7 @@ type Path struct {
|
|||||||
func NewTransport(cfg *common.ReticulumConfig) *Transport {
|
func NewTransport(cfg *common.ReticulumConfig) *Transport {
|
||||||
t := &Transport{
|
t := &Transport{
|
||||||
interfaces: make(map[string]common.NetworkInterface),
|
interfaces: make(map[string]common.NetworkInterface),
|
||||||
paths: make(map[string]*common.Path),
|
paths: make(map[string]*common.Path), // TODO: Load persisted path table from storage/destination_table for faster startup
|
||||||
seenAnnounces: make(map[string]bool),
|
seenAnnounces: make(map[string]bool),
|
||||||
announceRate: rate.NewLimiter(PROPAGATION_RATE, common.ONE),
|
announceRate: rate.NewLimiter(PROPAGATION_RATE, common.ONE),
|
||||||
mutex: sync.RWMutex{},
|
mutex: sync.RWMutex{},
|
||||||
@@ -178,6 +178,13 @@ func NewTransport(cfg *common.ReticulumConfig) *Transport {
|
|||||||
heldAnnounces: make(map[string]*PathAnnounceEntry),
|
heldAnnounces: make(map[string]*PathAnnounceEntry),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Path table persistence - Python Reticulum persists the path table to disk at
|
||||||
|
// storage/destination_table containing [timestamp, received_from, hops, expires, random_blobs, interface, packet_hash]
|
||||||
|
// for each known destination. This allows faster startup by not needing to re-discover all paths.
|
||||||
|
// However, NOT persisting provides better privacy as paths are ephemeral and forgotten on restart.
|
||||||
|
// Decision: Keep paths in-memory only for now (better privacy). If persistence is needed in the future,
|
||||||
|
// implement loadPathTable() and persistPathTable() methods with periodic saves.
|
||||||
|
|
||||||
transportIdent, err := identity.LoadOrCreateTransportIdentity()
|
transportIdent, err := identity.LoadOrCreateTransportIdentity()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.transportIdentity = transportIdent
|
t.transportIdentity = transportIdent
|
||||||
@@ -1231,19 +1238,59 @@ func (t *Transport) handleTransportPacket(data []byte, iface common.NetworkInter
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkt := &packet.Packet{Raw: append([]byte{0x00}, data...)}
|
||||||
|
if err := pkt.Unpack(); err != nil {
|
||||||
|
debug.Log(debug.DEBUG_INFO, "Failed to unpack transport packet", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
headerByte := data[0]
|
headerByte := data[0]
|
||||||
packetType := headerByte & 0x03
|
packetType := headerByte & 0x03
|
||||||
destType := (headerByte & 0x0C) >> 2
|
destType := (headerByte & 0x0C) >> 2
|
||||||
|
|
||||||
if packetType == packet.PacketTypeData && destType == DEST_TYPE_PLAIN {
|
if packetType == packet.PacketTypeData {
|
||||||
if len(data) < 19 {
|
if destType == DEST_TYPE_PLAIN {
|
||||||
return
|
if len(data) < 19 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
context := data[18]
|
||||||
|
|
||||||
|
if context == packet.ContextPathResponse {
|
||||||
|
t.handlePathResponse(data[19:], iface)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context := data[18]
|
destHash := pkt.DestinationHash
|
||||||
|
if len(destHash) > 16 {
|
||||||
|
destHash = destHash[:16]
|
||||||
|
}
|
||||||
|
|
||||||
if context == packet.ContextPathResponse {
|
debug.Log(debug.DEBUG_VERBOSE, "Looking up destination for data packet", "hash", fmt.Sprintf("%x", destHash))
|
||||||
t.handlePathResponse(data[19:], iface)
|
|
||||||
|
t.mutex.RLock()
|
||||||
|
destIface, exists := t.destinations[string(destHash)]
|
||||||
|
t.mutex.RUnlock()
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
debug.Log(debug.DEBUG_INFO, "Routing data packet to destination", "hash", fmt.Sprintf("%x", destHash))
|
||||||
|
|
||||||
|
destValue := reflect.ValueOf(destIface)
|
||||||
|
if destValue.IsValid() && !destValue.IsNil() {
|
||||||
|
method := destValue.MethodByName("Receive")
|
||||||
|
if method.IsValid() {
|
||||||
|
args := []reflect.Value{
|
||||||
|
reflect.ValueOf(pkt),
|
||||||
|
reflect.ValueOf(iface),
|
||||||
|
}
|
||||||
|
method.Call(args)
|
||||||
|
} else {
|
||||||
|
debug.Log(debug.DEBUG_VERBOSE, "Destination does not have Receive method")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debug.Log(debug.DEBUG_VERBOSE, "No destination registered for hash", "hash", fmt.Sprintf("%x", destHash))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user