-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmesh.go
104 lines (86 loc) · 2.11 KB
/
mesh.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"context"
"encoding/binary"
"fmt"
"net"
"github.com/pkg/errors"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network"
"github.com/songgao/packets/ethernet"
"github.com/songgao/water"
)
func meshHandler(i *water.Interface) func(stream network.Stream) {
return func(stream network.Stream) {
// TODO
// if _, ok := RevLookup[stream.Conn().RemotePeer()]; !ok {
// stream.Reset()
// return
// }
defer stream.Close()
var packet = make([]byte, MTU)
var packetSize = make([]byte, 2)
for {
_, err := stream.Read(packetSize)
if err != nil {
return
}
size := binary.LittleEndian.Uint16(packetSize)
var plen uint16 = 0
for plen < size {
tmp, err := stream.Read(packet[plen:size])
plen = uint16(tmp)
if err != nil {
return
}
}
i.Write(packet[:size])
}
}
}
func meshBridge(ctx context.Context, h host.Host, i *water.Interface) {
activeStreams := make(map[string]network.Stream)
var packet = make([]byte, MTU)
for {
plen, err := i.Read(packet)
if err != nil {
fmt.Println(err)
continue
}
dst := net.IPv4(packet[16], packet[17], packet[18], packet[19]).String() // TODO: use ethernet.Frame
if stream, ok := activeStreams[dst]; ok {
if err := binary.Write(stream, binary.LittleEndian, uint16(plen)); err == nil {
if _, err := stream.Write(packet[:plen]); err == nil {
continue
}
}
stream.Close()
delete(activeStreams, dst)
}
if peer, ok := PeerTable[dst]; ok {
stream, err := h.NewStream(ctx, peer, MeshProtocol.ID())
if err != nil {
continue
}
if err := binary.Write(stream, binary.LittleEndian, uint16(plen)); err != nil {
stream.Close()
continue
}
if _, err := stream.Write(packet[:plen]); err != nil {
stream.Close()
continue
}
activeStreams[dst] = stream
}
}
}
func getFrame(i *water.Interface) (ethernet.Frame, error) {
var frame ethernet.Frame
frame.Resize(MTU)
n, err := i.Read([]byte(frame))
if err != nil {
return frame, errors.Wrap(err, "could not read from interface")
}
frame = frame[:n]
return frame, nil
}