packages/hyprspace: support packet relaying
This commit is contained in:
parent
3d118b59ce
commit
02bee68d13
2 changed files with 69 additions and 46 deletions
|
@ -29,7 +29,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cfg *config.Config
|
cfg *config.Config
|
||||||
|
node host.Host
|
||||||
// iface is the tun device used to pass packets between
|
// iface is the tun device used to pass packets between
|
||||||
// Hyprspace and the user's machine.
|
// Hyprspace and the user's machine.
|
||||||
tunDev *tun.TUN
|
tunDev *tun.TUN
|
||||||
|
@ -108,6 +109,7 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
||||||
)
|
)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
host.SetStreamHandler(p2p.PeXProtocol, p2p.NewPeXStreamHandler(host, cfg))
|
host.SetStreamHandler(p2p.PeXProtocol, p2p.NewPeXStreamHandler(host, cfg))
|
||||||
|
node = host
|
||||||
|
|
||||||
for _, p := range cfg.Peers {
|
for _, p := range cfg.Peers {
|
||||||
host.ConnManager().Protect(p.ID, "/hyprspace/peer")
|
host.ConnManager().Protect(p.ID, "/hyprspace/peer")
|
||||||
|
@ -189,53 +191,57 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we already have an open connection to the destination peer.
|
sendPacket(*dst, packet, plen)
|
||||||
stream, ok := activeStreams[dst.ID]
|
|
||||||
if ok {
|
|
||||||
// Write out the packet's length to the libp2p stream to ensure
|
|
||||||
// we know the full size of the packet at the other end.
|
|
||||||
err = binary.Write(stream, binary.LittleEndian, uint16(plen))
|
|
||||||
if err == nil {
|
|
||||||
// Write the packet out to the libp2p stream.
|
|
||||||
// If everyting succeeds continue on to the next packet.
|
|
||||||
_, err = stream.Write(packet[:plen])
|
|
||||||
if err == nil {
|
|
||||||
stream.SetWriteDeadline(time.Now().Add(25 * time.Second))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If we encounter an error when writing to a stream we should
|
|
||||||
// close that stream and delete it from the active stream map.
|
|
||||||
stream.Close()
|
|
||||||
delete(activeStreams, dst.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
stream, err = host.NewStream(ctx, dst.ID, p2p.Protocol)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("[!] Failed to open stream to " + dst.ID.String())
|
|
||||||
go p2p.Rediscover()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
stream.SetWriteDeadline(time.Now().Add(25 * time.Second))
|
|
||||||
// Write packet length
|
|
||||||
err = binary.Write(stream, binary.LittleEndian, uint16(plen))
|
|
||||||
if err != nil {
|
|
||||||
stream.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Write the packet
|
|
||||||
_, err = stream.Write(packet[:plen])
|
|
||||||
if err != nil {
|
|
||||||
stream.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all succeeds when writing the packet to the stream
|
|
||||||
// we should reuse this stream by adding it active streams map.
|
|
||||||
activeStreams[dst.ID] = stream
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendPacket(dst config.Peer, packet []byte, plen int) {
|
||||||
|
// Check if we already have an open connection to the destination peer.
|
||||||
|
stream, ok := activeStreams[dst.ID]
|
||||||
|
if ok {
|
||||||
|
// Write out the packet's length to the libp2p stream to ensure
|
||||||
|
// we know the full size of the packet at the other end.
|
||||||
|
err := binary.Write(stream, binary.LittleEndian, uint16(plen))
|
||||||
|
if err == nil {
|
||||||
|
// Write the packet out to the libp2p stream.
|
||||||
|
// If everyting succeeds continue on to the next packet.
|
||||||
|
_, err = stream.Write(packet[:plen])
|
||||||
|
if err == nil {
|
||||||
|
stream.SetWriteDeadline(time.Now().Add(25 * time.Second))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we encounter an error when writing to a stream we should
|
||||||
|
// close that stream and delete it from the active stream map.
|
||||||
|
stream.Close()
|
||||||
|
delete(activeStreams, dst.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
stream, err := node.NewStream(ctx, dst.ID, p2p.Protocol)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[!] Failed to open stream to " + dst.ID.String())
|
||||||
|
go p2p.Rediscover()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stream.SetWriteDeadline(time.Now().Add(25 * time.Second))
|
||||||
|
// Write packet length
|
||||||
|
err = binary.Write(stream, binary.LittleEndian, uint16(plen))
|
||||||
|
if err != nil {
|
||||||
|
stream.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Write the packet
|
||||||
|
_, err = stream.Write(packet[:plen])
|
||||||
|
if err != nil {
|
||||||
|
stream.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all succeeds when writing the packet to the stream
|
||||||
|
// we should reuse this stream by adding it active streams map.
|
||||||
|
activeStreams[dst.ID] = stream
|
||||||
|
}
|
||||||
|
|
||||||
func signalHandler(ctx context.Context, host host.Host, lockPath string, dht *dht.IpfsDHT) {
|
func signalHandler(ctx context.Context, host host.Host, lockPath string, dht *dht.IpfsDHT) {
|
||||||
exitCh := make(chan os.Signal, 1)
|
exitCh := make(chan os.Signal, 1)
|
||||||
rebootstrapCh := make(chan os.Signal, 1)
|
rebootstrapCh := make(chan os.Signal, 1)
|
||||||
|
@ -324,7 +330,15 @@ func streamHandler(stream network.Stream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stream.SetWriteDeadline(time.Now().Add(25 * time.Second))
|
stream.SetWriteDeadline(time.Now().Add(25 * time.Second))
|
||||||
tunDev.Iface.Write(packet[:size])
|
dstIP := net.IPv4(packet[16], packet[17], packet[18], packet[19])
|
||||||
|
route, found := config.FindRouteForIP(cfg.Routes, dstIP)
|
||||||
|
if !found {
|
||||||
|
// not found means the packet is for us
|
||||||
|
tunDev.Iface.Write(packet[:size])
|
||||||
|
} else {
|
||||||
|
// FIXME: should decrease the TTL here
|
||||||
|
sendPacket(route.Target, packet, int(plen))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,3 +98,12 @@ func FindRoute(routes []Route, needle net.IPNet) (*Route, bool) {
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FindRouteForIP(routes []Route, needle net.IP) (*Route, bool) {
|
||||||
|
for _, r := range routes {
|
||||||
|
if r.Network.Contains(needle) {
|
||||||
|
return &r, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue