Cleanup and speedup network convergence along with direct messaging for connect and solicit
This commit is contained in:
@@ -327,6 +327,7 @@ func (t *tun) process() {
|
||||
// and the message is being sent outbound via
|
||||
// a dialled connection don't use this link
|
||||
if loopback && msg.outbound {
|
||||
log.Tracef("Link for node %s is loopback", node)
|
||||
err = errors.New("link is loopback")
|
||||
continue
|
||||
}
|
||||
@@ -334,6 +335,7 @@ func (t *tun) process() {
|
||||
// if the message was being returned by the loopback listener
|
||||
// send it back up the loopback link only
|
||||
if msg.loopback && !loopback {
|
||||
log.Tracef("Link for message %s is loopback", node)
|
||||
err = errors.New("link is not loopback")
|
||||
continue
|
||||
}
|
||||
@@ -363,7 +365,7 @@ func (t *tun) process() {
|
||||
// send the message
|
||||
for _, link := range sendTo {
|
||||
// send the message via the current link
|
||||
log.Tracef("Sending %+v to %s", newMsg.Header, link.Remote())
|
||||
log.Tracef("Tunnel sending %+v to %s", newMsg.Header, link.Remote())
|
||||
|
||||
if errr := link.Send(newMsg); errr != nil {
|
||||
log.Debugf("Tunnel error sending %+v to %s: %v", newMsg.Header, link.Remote(), errr)
|
||||
@@ -502,6 +504,7 @@ func (t *tun) listen(link *link) {
|
||||
// nothing more to do
|
||||
continue
|
||||
case "close":
|
||||
log.Debugf("Tunnel link %s received close message", link.Remote())
|
||||
// if there is no channel then we close the link
|
||||
// as its a signal from the other side to close the connection
|
||||
if len(channel) == 0 {
|
||||
@@ -555,9 +558,11 @@ func (t *tun) listen(link *link) {
|
||||
// a continued session
|
||||
case "session":
|
||||
// process message
|
||||
log.Tracef("Received %+v from %s", msg.Header, link.Remote())
|
||||
log.Tracef("Tunnel received %+v from %s", msg.Header, link.Remote())
|
||||
// an announcement of a channel listener
|
||||
case "announce":
|
||||
log.Tracef("Tunnel received %+v from %s", msg.Header, link.Remote())
|
||||
|
||||
// process the announcement
|
||||
channels := strings.Split(channel, ",")
|
||||
|
||||
@@ -629,7 +634,7 @@ func (t *tun) listen(link *link) {
|
||||
s, exists = t.getSession(channel, "listener")
|
||||
// only return accept to the session
|
||||
case mtype == "accept":
|
||||
log.Debugf("Received accept message for channel: %s session: %s", channel, sessionId)
|
||||
log.Debugf("Tunnel received accept message for channel: %s session: %s", channel, sessionId)
|
||||
s, exists = t.getSession(channel, sessionId)
|
||||
if exists && s.accepted {
|
||||
continue
|
||||
@@ -649,7 +654,7 @@ func (t *tun) listen(link *link) {
|
||||
|
||||
// bail if no session or listener has been found
|
||||
if !exists {
|
||||
log.Debugf("Tunnel skipping no channel: %s session: %s exists", channel, sessionId)
|
||||
log.Tracef("Tunnel skipping no channel: %s session: %s exists", channel, sessionId)
|
||||
// drop it, we don't care about
|
||||
// messages we don't know about
|
||||
continue
|
||||
@@ -665,7 +670,7 @@ func (t *tun) listen(link *link) {
|
||||
// otherwise process
|
||||
}
|
||||
|
||||
log.Debugf("Tunnel using channel: %s session: %s type: %s", s.channel, s.session, mtype)
|
||||
log.Tracef("Tunnel using channel: %s session: %s type: %s", s.channel, s.session, mtype)
|
||||
|
||||
// construct a new transport message
|
||||
tmsg := &transport.Message{
|
||||
@@ -740,7 +745,7 @@ func (t *tun) keepalive(link *link) {
|
||||
"Micro-Tunnel-Id": t.id,
|
||||
},
|
||||
}); err != nil {
|
||||
log.Debugf("Error sending keepalive to link %v: %v", link.Remote(), err)
|
||||
log.Debugf("Tunnel error sending keepalive to link %v: %v", link.Remote(), err)
|
||||
t.delLink(link.Remote())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package tunnel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -14,7 +15,11 @@ import (
|
||||
type link struct {
|
||||
transport.Socket
|
||||
|
||||
// transport to use for connections
|
||||
transport transport.Transport
|
||||
|
||||
sync.RWMutex
|
||||
|
||||
// stops the link
|
||||
closed chan bool
|
||||
// link state channel for testing link
|
||||
@@ -65,6 +70,8 @@ var (
|
||||
linkRequest = []byte{0, 0, 0, 0}
|
||||
// the 4 byte 1 filled packet sent to determine link state
|
||||
linkResponse = []byte{1, 1, 1, 1}
|
||||
|
||||
ErrLinkConnectTimeout = errors.New("link connect timeout")
|
||||
)
|
||||
|
||||
func newLink(s transport.Socket) *link {
|
||||
@@ -72,8 +79,8 @@ func newLink(s transport.Socket) *link {
|
||||
Socket: s,
|
||||
id: uuid.New().String(),
|
||||
lastKeepAlive: time.Now(),
|
||||
channels: make(map[string]time.Time),
|
||||
closed: make(chan bool),
|
||||
channels: make(map[string]time.Time),
|
||||
state: make(chan *packet, 64),
|
||||
sendQueue: make(chan *packet, 128),
|
||||
recvQueue: make(chan *packet, 128),
|
||||
@@ -87,6 +94,32 @@ func newLink(s transport.Socket) *link {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *link) connect(addr string) error {
|
||||
c, err := l.transport.Dial(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.Lock()
|
||||
l.Socket = c
|
||||
l.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *link) accept(sock transport.Socket) error {
|
||||
l.Lock()
|
||||
l.Socket = sock
|
||||
l.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *link) setLoopback(v bool) {
|
||||
l.Lock()
|
||||
l.loopback = v
|
||||
l.Unlock()
|
||||
}
|
||||
|
||||
// setRate sets the bits per second rate as a float64
|
||||
func (l *link) setRate(bits int64, delta time.Duration) {
|
||||
// rate of send in bits per nanosecond
|
||||
@@ -201,11 +234,15 @@ func (l *link) manage() {
|
||||
t := time.NewTicker(time.Minute)
|
||||
defer t.Stop()
|
||||
|
||||
// get link id
|
||||
linkId := l.Id()
|
||||
|
||||
// used to send link state packets
|
||||
send := func(b []byte) error {
|
||||
return l.Send(&transport.Message{
|
||||
Header: map[string]string{
|
||||
"Micro-Method": "link",
|
||||
"Micro-Method": "link",
|
||||
"Micro-Link-Id": linkId,
|
||||
}, Body: b,
|
||||
})
|
||||
}
|
||||
@@ -229,9 +266,7 @@ func (l *link) manage() {
|
||||
// check the type of message
|
||||
switch {
|
||||
case bytes.Equal(p.message.Body, linkRequest):
|
||||
l.RLock()
|
||||
log.Tracef("Link %s received link request %v", l.id, p.message.Body)
|
||||
l.RUnlock()
|
||||
log.Tracef("Link %s received link request", linkId)
|
||||
|
||||
// send response
|
||||
if err := send(linkResponse); err != nil {
|
||||
@@ -242,9 +277,7 @@ func (l *link) manage() {
|
||||
case bytes.Equal(p.message.Body, linkResponse):
|
||||
// set round trip time
|
||||
d := time.Since(now)
|
||||
l.RLock()
|
||||
log.Tracef("Link %s received link response in %v", p.message.Body, d)
|
||||
l.RUnlock()
|
||||
log.Tracef("Link %s received link response in %v", linkId, d)
|
||||
// set the RTT
|
||||
l.setRTT(d)
|
||||
}
|
||||
@@ -309,6 +342,12 @@ func (l *link) Rate() float64 {
|
||||
return l.rate
|
||||
}
|
||||
|
||||
func (l *link) Loopback() bool {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
return l.loopback
|
||||
}
|
||||
|
||||
// Length returns the roundtrip time as nanoseconds (lower is better).
|
||||
// Returns 0 where no measurement has been taken.
|
||||
func (l *link) Length() int64 {
|
||||
@@ -320,7 +359,6 @@ func (l *link) Length() int64 {
|
||||
func (l *link) Id() string {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
|
||||
return l.id
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ func (t *tunListener) process() {
|
||||
|
||||
// get a session
|
||||
sess, ok := conns[sessionId]
|
||||
log.Debugf("Tunnel listener received channel %s session %s type %s exists: %t", m.channel, sessionId, m.typ, ok)
|
||||
log.Tracef("Tunnel listener received channel %s session %s type %s exists: %t", m.channel, sessionId, m.typ, ok)
|
||||
if !ok {
|
||||
// we only process open and session types
|
||||
switch m.typ {
|
||||
@@ -159,7 +159,7 @@ func (t *tunListener) process() {
|
||||
case <-sess.closed:
|
||||
delete(conns, sessionId)
|
||||
case sess.recv <- m:
|
||||
log.Debugf("Tunnel listener sent to recv chan channel %s session %s type %s", m.channel, sessionId, m.typ)
|
||||
log.Tracef("Tunnel listener sent to recv chan channel %s session %s type %s", m.channel, sessionId, m.typ)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,11 +356,11 @@ func (s *session) Recv(m *transport.Message) error {
|
||||
}
|
||||
|
||||
//log.Tracef("Received %+v from recv backlog", msg)
|
||||
log.Debugf("Received %+v from recv backlog", msg)
|
||||
log.Tracef("Received %+v from recv backlog", msg)
|
||||
|
||||
// decrypt the received payload using the token
|
||||
// we have to used msg.session because multicast has a shared
|
||||
// session id of "multicast" in this session struct on
|
||||
// session id of "multicast" in this session struct on
|
||||
// the listener side
|
||||
body, err := Decrypt(msg.data.Body, s.token+s.channel+msg.session)
|
||||
if err != nil {
|
||||
|
||||
@@ -64,7 +64,9 @@ type Link interface {
|
||||
Length() int64
|
||||
// Current transfer rate as bits per second (lower is better)
|
||||
Rate() float64
|
||||
// State of the link e.g connected/closed
|
||||
// Is this a loopback link
|
||||
Loopback() bool
|
||||
// State of the link: connected/closed/error
|
||||
State() string
|
||||
// honours transport socket
|
||||
transport.Socket
|
||||
|
||||
Reference in New Issue
Block a user