micro/tunnel/listener.go

116 lines
2.3 KiB
Go
Raw Normal View History

2019-08-07 18:44:33 +01:00
package tunnel
import (
"io"
2019-08-11 18:11:33 +01:00
"github.com/micro/go-micro/util/log"
2019-08-07 18:44:33 +01:00
)
type tunListener struct {
// address of the listener
2019-08-30 20:05:00 +01:00
channel string
2019-08-07 18:44:33 +01:00
// the accept channel
2019-08-30 20:05:00 +01:00
accept chan *session
2019-08-07 18:44:33 +01:00
// the channel to close
closed chan bool
// the tunnel closed channel
tunClosed chan bool
2019-08-30 20:05:00 +01:00
// the listener session
session *session
2019-08-07 18:44:33 +01:00
}
func (t *tunListener) process() {
// our connection map for session
2019-08-30 20:05:00 +01:00
conns := make(map[string]*session)
2019-08-07 18:44:33 +01:00
for {
select {
case <-t.closed:
return
// receive a new message
2019-08-30 20:05:00 +01:00
case m := <-t.session.recv:
// get a session
sess, ok := conns[m.session]
2019-08-11 18:11:33 +01:00
log.Debugf("Tunnel listener received id %s session %s exists: %t", m.id, m.session, ok)
2019-08-07 18:44:33 +01:00
if !ok {
2019-08-30 20:05:00 +01:00
// create a new session session
sess = &session{
// the id of the remote side
2019-08-07 18:44:33 +01:00
id: m.id,
2019-08-30 20:05:00 +01:00
// the channel
channel: m.channel,
2019-08-07 18:44:33 +01:00
// the session id
session: m.session,
// is loopback conn
loopback: m.loopback,
2019-08-29 12:42:27 +01:00
// the link the message was received on
link: m.link,
2019-08-07 18:44:33 +01:00
// close chan
closed: make(chan bool),
// recv called by the acceptor
recv: make(chan *message, 128),
// use the internal send buffer
2019-08-30 20:05:00 +01:00
send: t.session.send,
2019-08-07 18:44:33 +01:00
// wait
wait: make(chan bool),
2019-08-30 20:05:00 +01:00
// error channel
errChan: make(chan error, 1),
2019-08-07 18:44:33 +01:00
}
2019-08-30 20:05:00 +01:00
// save the session
conns[m.session] = sess
2019-08-07 18:44:33 +01:00
// send to accept chan
select {
case <-t.closed:
return
2019-08-30 20:05:00 +01:00
case t.accept <- sess:
2019-08-07 18:44:33 +01:00
}
}
// send this to the accept chan
select {
2019-08-30 20:05:00 +01:00
case <-sess.closed:
2019-08-07 18:44:33 +01:00
delete(conns, m.session)
2019-08-30 20:05:00 +01:00
case sess.recv <- m:
2019-08-11 18:11:33 +01:00
log.Debugf("Tunnel listener sent to recv chan id %s session %s", m.id, m.session)
2019-08-07 18:44:33 +01:00
}
}
}
}
2019-08-30 20:05:00 +01:00
func (t *tunListener) Channel() string {
return t.channel
2019-08-07 18:44:33 +01:00
}
// Close closes tunnel listener
2019-08-07 18:44:33 +01:00
func (t *tunListener) Close() error {
select {
case <-t.closed:
return nil
default:
close(t.closed)
}
return nil
}
// Everytime accept is called we essentially block till we get a new connection
2019-08-30 20:05:00 +01:00
func (t *tunListener) Accept() (Session, error) {
2019-08-07 18:44:33 +01:00
select {
2019-08-30 20:05:00 +01:00
// if the session is closed return
2019-08-07 18:44:33 +01:00
case <-t.closed:
return nil, io.EOF
case <-t.tunClosed:
// close the listener when the tunnel closes
2019-08-11 18:11:33 +01:00
t.Close()
return nil, io.EOF
2019-08-07 18:44:33 +01:00
// wait for a new connection
case c, ok := <-t.accept:
if !ok {
return nil, io.EOF
}
return c, nil
}
return nil, nil
}