Add new reject channel to router so we can send back rejected packets to adapter (e.g. for ICMPv6 Packet Too Big), implement ICMPv6 PTB in TUN/TAP instead of router

This commit is contained in:
Neil Alexander 2019-03-28 09:50:13 +00:00
parent 0715e829c2
commit eb22ed44ac
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
3 changed files with 135 additions and 96 deletions

View file

@ -13,12 +13,13 @@ type Adapter struct {
Core *Core
Send chan<- []byte
Recv <-chan []byte
Reject <-chan RejectedPacket
Reconfigure chan chan error
}
// Defines the minimum required functions for an adapter type
type adapterImplementation interface {
Init(*config.NodeState, *log.Logger, chan<- []byte, <-chan []byte)
Init(*config.NodeState, *log.Logger, chan<- []byte, <-chan []byte, <-chan RejectedPacket)
Name() string
MTU() int
IsTAP() bool
@ -29,9 +30,10 @@ type adapterImplementation interface {
}
// Initialises the adapter.
func (adapter *Adapter) Init(config *config.NodeState, log *log.Logger, send chan<- []byte, recv <-chan []byte) {
func (adapter *Adapter) Init(config *config.NodeState, log *log.Logger, send chan<- []byte, recv <-chan []byte, reject <-chan RejectedPacket) {
log.Traceln("Adapter setup - given channels:", send, recv)
adapter.Send = send
adapter.Recv = recv
adapter.Reject = reject
adapter.Reconfigure = make(chan chan error, 1)
}

View file

@ -44,6 +44,7 @@ type router struct {
tun adapterImplementation // TUN/TAP adapter
recv chan<- []byte // place where the tun pulls received packets from
send <-chan []byte // place where the tun puts outgoing packets
reject chan<- RejectedPacket // place where we send error packets back to tun
reset chan struct{} // signal that coords changed (re-init sessions/dht)
admin chan func() // pass a lambda for the admin socket to query stuff
cryptokey cryptokey
@ -56,6 +57,19 @@ type router_recvPacket struct {
sinfo *sessionInfo
}
type RejectedPacketReason int
const (
// The router rejected the packet because it is too big for the session
PacketTooBig = 1 + iota
)
type RejectedPacket struct {
Reason RejectedPacketReason
Packet []byte
Detail interface{}
}
// Initializes the router struct, which includes setting up channels to/from the tun/tap.
func (r *router) init(core *Core) {
r.core = core
@ -103,8 +117,10 @@ func (r *router) init(core *Core) {
r.toRecv = make(chan router_recvPacket, 32)
recv := make(chan []byte, 32)
send := make(chan []byte, 32)
reject := make(chan RejectedPacket, 32)
r.recv = recv
r.send = send
r.reject = reject
r.reset = make(chan struct{}, 1)
r.admin = make(chan func(), 32)
r.nodeinfo.init(r.core)
@ -112,7 +128,7 @@ func (r *router) init(core *Core) {
r.nodeinfo.setNodeInfo(r.core.config.Current.NodeInfo, r.core.config.Current.NodeInfoPrivacy)
r.core.config.Mutex.RUnlock()
r.cryptokey.init(r.core)
r.tun.Init(&r.core.config, r.core.log, send, recv)
r.tun.Init(&r.core.config, r.core.log, send, recv, reject)
}
// Starts the mainLoop goroutine.
@ -303,25 +319,18 @@ func (r *router) sendPacket(bs []byte) {
// Generate an ICMPv6 Packet Too Big for packets larger than session MTU
if len(bs) > int(sinfo.getMTU()) {
// Get the size of the oversized payload, up to a max of 900 bytes
/*window := 900
window := 900
if int(sinfo.getMTU()) < window {
window = int(sinfo.getMTU())
}
// Create the Packet Too Big response
ptb := &icmp.PacketTooBig{
MTU: int(sinfo.getMTU()),
Data: bs[:window],
// Send the error back to the adapter
r.reject <- RejectedPacket{
Reason: PacketTooBig,
Packet: bs[:window],
Detail: int(sinfo.getMTU()),
}
// Create the ICMPv6 response from it
icmpv6Buf, err := CreateICMPv6(
bs[8:24], bs[24:40],
ipv6.ICMPTypePacketTooBig, 0, ptb)
if err == nil {
r.recv <- icmpv6Buf
}*/
// Don't continue - drop the packet
return
}