mirror of https://gogs.blitter.com/RLabs/xs
WIP tunnel states, re-dial when not required needs debugging.
This commit is contained in:
parent
dd37922fb2
commit
3b35751e2e
|
@ -56,7 +56,6 @@ const (
|
||||||
|
|
||||||
// Tunnel setup/control/status
|
// Tunnel setup/control/status
|
||||||
CSOTunSetup // client -> server tunnel setup request (dstport)
|
CSOTunSetup // client -> server tunnel setup request (dstport)
|
||||||
CSOTunInUse // server -> client: tunnel rport is in use
|
|
||||||
CSOTunSetupAck // server -> client tunnel setup ack
|
CSOTunSetupAck // server -> client tunnel setup ack
|
||||||
CSOTunAccept // client -> server: tunnel client got an Accept()
|
CSOTunAccept // client -> server: tunnel client got an Accept()
|
||||||
// (Do we need a CSOTunAcceptAck server->client?)
|
// (Do we need a CSOTunAcceptAck server->client?)
|
||||||
|
@ -66,23 +65,26 @@ const (
|
||||||
CSOTunHangup // client -> server: tunnel lport hung up
|
CSOTunHangup // client -> server: tunnel lport hung up
|
||||||
)
|
)
|
||||||
|
|
||||||
// TunEndpoint.tunCtl control values
|
// TunEndpoint.tunCtl control values - used to control workers for client or server tunnels
|
||||||
|
// depending on the code
|
||||||
const (
|
const (
|
||||||
TunCtl_AcceptedClient = 'a' // client side has accept()ed a conn
|
TunCtl_Client_Listen = 'a'
|
||||||
|
|
||||||
|
TunCtl_Server_Dial = 'd' // server has dialled OK, client side can accept() conns
|
||||||
// [CSOTunAccept]
|
// [CSOTunAccept]
|
||||||
// status: client listen() worker accepted conn on lport
|
// status: client listen() worker accepted conn on lport
|
||||||
// action:server side should dial() rport on client's behalf
|
// action:server side should dial() rport on client's behalf
|
||||||
|
|
||||||
TunCtl_LostClient = 'h' // client side has hung up
|
TunCtl_Info_Hangup = 'h' // client side has hung up
|
||||||
// [CSOTunHangup]
|
// [CSOTunHangup]
|
||||||
// status: client side conn hung up from lport
|
// status: client side conn hung up from lport
|
||||||
// action:server side should hang up on rport, on client's behalf
|
// action:server side should hang up on rport, on client's behalf
|
||||||
|
|
||||||
TunCtl_ConnRefused = 'r' // server side couldn't complete tunnel
|
TunCtl_Info_ConnRefused = 'r' // server side couldn't complete tunnel
|
||||||
// [CSOTunRefused]
|
// [CSOTunRefused]
|
||||||
// status:server side could not dial() remote side
|
// status:server side could not dial() remote side
|
||||||
|
|
||||||
TunCtl_LostConn = 'l' // server side disconnected
|
TunCtl_Info_LostConn = 'x' // server side disconnected
|
||||||
// [CSOTunDisconn]
|
// [CSOTunDisconn]
|
||||||
// status:server side lost connection to rport
|
// status:server side lost connection to rport
|
||||||
// action:client should disconnect accepted lport connection
|
// action:client should disconnect accepted lport connection
|
||||||
|
|
|
@ -85,7 +85,7 @@ type (
|
||||||
Cols uint16
|
Cols uint16
|
||||||
|
|
||||||
chaff ChaffConfig
|
chaff ChaffConfig
|
||||||
tuns map[uint16]*TunEndpoint
|
tuns *map[uint16](*TunEndpoint)
|
||||||
|
|
||||||
closeStat *CSOType // close status (CSOExitStatus)
|
closeStat *CSOType // close status (CSOExitStatus)
|
||||||
r cipher.Stream //read cipherStream
|
r cipher.Stream //read cipherStream
|
||||||
|
@ -208,6 +208,8 @@ func _new(kexAlg KEXAlg, conn *net.Conn) (hc *Conn, e error) {
|
||||||
closeStat: new(CSOType),
|
closeStat: new(CSOType),
|
||||||
WinCh: make(chan WinSize, 1),
|
WinCh: make(chan WinSize, 1),
|
||||||
dBuf: new(bytes.Buffer)}
|
dBuf: new(bytes.Buffer)}
|
||||||
|
tempMap := make(map[uint16]*TunEndpoint)
|
||||||
|
hc.tuns = &tempMap
|
||||||
|
|
||||||
*hc.closeStat = CSEStillOpen // open or prematurely-closed status
|
*hc.closeStat = CSEStillOpen // open or prematurely-closed status
|
||||||
|
|
||||||
|
@ -814,39 +816,58 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
// server side tunnel setup in response to client
|
// server side tunnel setup in response to client
|
||||||
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
||||||
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
||||||
logger.LogDebug(fmt.Sprintf("Read(): Tunnel setup [%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("mapkey is %d", rport))
|
||||||
hc.StartServerTunnel(lport, rport)
|
if _, ok := (*hc.tuns)[rport]; !ok {
|
||||||
hc.tuns[rport].Ctl <- 'a' // Dial() rport
|
// tunnel first-time open
|
||||||
|
logger.LogDebug(fmt.Sprintf("[Server] Got Initial CSOTunSetup [%d:%d]", lport, rport))
|
||||||
|
hc.StartServerTunnel(lport, rport)
|
||||||
|
} else {
|
||||||
|
logger.LogDebug(fmt.Sprintf("[Server] Got CSOTunSetup [%d:%d]", lport, rport))
|
||||||
|
}
|
||||||
|
(*hc.tuns)[rport].Ctl <- 'd' // Dial() rport
|
||||||
} else if ctrlStatOp == CSOTunSetupAck {
|
} else if ctrlStatOp == CSOTunSetupAck {
|
||||||
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
||||||
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
||||||
logger.LogDebug(fmt.Sprintf("Read(): Tunnel setup ack [%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("mapkey is %d\n", rport))
|
||||||
hc.dBuf.Write(payloadBytes)
|
if _, ok := (*hc.tuns)[rport]; !ok {
|
||||||
|
// tunnel first-time open
|
||||||
|
logger.LogDebug(fmt.Sprintf("[Client] Got Initial CSOTunSetupAck [%d:%d]", lport, rport))
|
||||||
|
hc.StartClientTunnel(lport, rport)
|
||||||
|
} else {
|
||||||
|
logger.LogDebug(fmt.Sprintf("[Client] Got CSOTunSetupAck [%d:%d]", lport, rport))
|
||||||
|
}
|
||||||
|
(*hc.tuns)[rport].Ctl <- 'a' // Listen() for lport connection
|
||||||
} else if ctrlStatOp == CSOTunRefused {
|
} else if ctrlStatOp == CSOTunRefused {
|
||||||
// client side has been told nothing is listening on rport
|
// client side receiving CSOTunRefused means the remote side
|
||||||
|
// could not dial() rport. So we cannot yet listen()
|
||||||
|
// for client-side on lport.
|
||||||
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
||||||
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
||||||
logger.LogDebug(fmt.Sprintf("Read(): Tunnel refused [%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("mapkey is %d\n", rport))
|
||||||
hc.dBuf.Write(payloadBytes)
|
logger.LogDebug(fmt.Sprintf("[Client] Got CSOTunRefused [%d:%d]", lport, rport))
|
||||||
|
(*hc.tuns)[rport].Ctl <- 'r' // client should NOT Listen()
|
||||||
} else if ctrlStatOp == CSOTunDisconn {
|
} else if ctrlStatOp == CSOTunDisconn {
|
||||||
// server side's rport has disconnected (server lost)
|
// server side's rport has disconnected (server lost)
|
||||||
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
||||||
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
||||||
logger.LogDebug(fmt.Sprintf("Read(): Tunnel server disconnected [%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("mapkey is %d\n", rport))
|
||||||
hc.dBuf.Write(payloadBytes)
|
logger.LogDebug(fmt.Sprintf("[Client] Got CSOTunDisconn [%d:%d]", lport, rport))
|
||||||
|
(*hc.tuns)[rport].Ctl <- 'x' // client should hangup on current lport conn
|
||||||
} else if ctrlStatOp == CSOTunHangup {
|
} else if ctrlStatOp == CSOTunHangup {
|
||||||
// client side's lport has hung up
|
// client side's lport has hung up
|
||||||
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
||||||
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
||||||
logger.LogDebug(fmt.Sprintf("Read(): Tunnel client hung up [%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("mapkey is %d\n", rport))
|
||||||
hc.dBuf.Write(payloadBytes)
|
logger.LogDebug(fmt.Sprintf("[Server] Got CSOTunHangup [%d:%d]", lport, rport))
|
||||||
|
(*hc.tuns)[rport].Ctl <- 'h' // server should hang up on currently-dialled rport
|
||||||
} else if ctrlStatOp == CSOTunData {
|
} else if ctrlStatOp == CSOTunData {
|
||||||
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
|
||||||
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
|
||||||
|
logger.LogDebug(fmt.Sprintf("mapkey is %d\n", rport))
|
||||||
//fmt.Printf("[Got CSOTunData: [lport %d:rport %d] data:%v\n", lport, rport, payloadBytes[4:])
|
//fmt.Printf("[Got CSOTunData: [lport %d:rport %d] data:%v\n", lport, rport, payloadBytes[4:])
|
||||||
if hc.tuns[rport] != nil {
|
if _, ok := (*hc.tuns)[rport]; ok {
|
||||||
logger.LogDebug(fmt.Sprintf("[Writing data to rport [%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("[Writing data to rport [%d:%d]", lport, rport))
|
||||||
hc.tuns[rport].Data <- payloadBytes[4:]
|
(*hc.tuns)[rport].Data <- payloadBytes[4:]
|
||||||
} else {
|
} else {
|
||||||
logger.LogDebug(fmt.Sprintf("[Attempt to write data to closed tun [%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("[Attempt to write data to closed tun [%d:%d]", lport, rport))
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,118 +48,147 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (hc *Conn) InitTunEndpoint(lp uint16, p string /* net.Addr */, rp uint16) {
|
func (hc *Conn) InitTunEndpoint(lp uint16, p string /* net.Addr */, rp uint16) {
|
||||||
if hc.tuns == nil {
|
if (*hc.tuns) == nil {
|
||||||
hc.tuns = make(map[uint16]*TunEndpoint)
|
(*hc.tuns) = make(map[uint16]*TunEndpoint)
|
||||||
}
|
}
|
||||||
if hc.tuns[rp] == nil {
|
if (*hc.tuns)[rp] == nil {
|
||||||
var addrs []net.Addr
|
var addrs []net.Addr
|
||||||
if p == "" {
|
if p == "" {
|
||||||
addrs, _ = net.InterfaceAddrs()
|
addrs, _ = net.InterfaceAddrs()
|
||||||
p = addrs[0].String()
|
p = addrs[0].String()
|
||||||
}
|
}
|
||||||
hc.tuns[rp] = &TunEndpoint{ /*Status: CSOTunSetup,*/ Peer: p,
|
(*hc.tuns)[rp] = &TunEndpoint{ /*Status: CSOTunSetup,*/ Peer: p,
|
||||||
Lport: lp, Rport: rp, Data: make(chan []byte, 1),
|
Lport: lp, Rport: rp, Data: make(chan []byte, 1),
|
||||||
Ctl: make(chan rune, 1)}
|
Ctl: make(chan rune, 1)}
|
||||||
logger.LogDebug(fmt.Sprintf("InitTunEndpoint [%d:%s:%d]\n", lp, p, rp))
|
logger.LogDebug(fmt.Sprintf("InitTunEndpoint [%d:%s:%d]", lp, p, rp))
|
||||||
|
} else {
|
||||||
|
logger.LogDebug(fmt.Sprintf("InitTunEndpoint [reusing] [%d:%s:%d]", (*hc.tuns)[rp].Lport, (*hc.tuns)[rp].Peer, (*hc.tuns)[rp].Rport))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *Conn) StartClientTunnel(lport, rport uint16) {
|
func (hc *Conn) StartClientTunnel(lport, rport uint16) {
|
||||||
hc.InitTunEndpoint(lport, "", rport)
|
hc.InitTunEndpoint(lport, "", rport)
|
||||||
t := hc.tuns[rport] // for convenience
|
t := (*hc.tuns)[rport] // for convenience
|
||||||
|
var l HKExListener
|
||||||
go func() {
|
go func() {
|
||||||
logger.LogDebug(fmt.Sprintf("Listening for client tunnel port %d", lport))
|
weAreListening := false
|
||||||
l, e := net.Listen("tcp", fmt.Sprintf(":%d", lport))
|
for cmd := range t.Ctl {
|
||||||
if e != nil {
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Listening for client tunnel port %d", lport))
|
||||||
logger.LogDebug(fmt.Sprintf("[Could not get lport %d! (%s)", lport, e))
|
|
||||||
} else {
|
|
||||||
defer l.Close()
|
|
||||||
for {
|
|
||||||
c, e := l.Accept()
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
c.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
|
if cmd == 'a' && !weAreListening {
|
||||||
|
l, e := net.Listen("tcp", fmt.Sprintf(":%d", lport))
|
||||||
if e != nil {
|
if e != nil {
|
||||||
logger.LogDebug(fmt.Sprintf("Accept() got error(%v), hanging up.", e))
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Could not get lport %d! (%s)", lport, e))
|
||||||
break
|
|
||||||
} else {
|
} else {
|
||||||
logger.LogDebug(fmt.Sprintln("Accepted tunnel client"))
|
weAreListening = true
|
||||||
|
for {
|
||||||
// outside client -> tunnel lport
|
c, e := l.Accept()
|
||||||
go func() {
|
|
||||||
var tunDst bytes.Buffer
|
var tunDst bytes.Buffer
|
||||||
|
// ask server to dial() its side, rport
|
||||||
binary.Write(&tunDst, binary.BigEndian, lport)
|
binary.Write(&tunDst, binary.BigEndian, lport)
|
||||||
binary.Write(&tunDst, binary.BigEndian, rport)
|
binary.Write(&tunDst, binary.BigEndian, rport)
|
||||||
for {
|
hc.WritePacket(tunDst.Bytes(), CSOTunSetup)
|
||||||
rBuf := make([]byte, 1024)
|
|
||||||
//Read data from c, encrypt/write via hc to client(lport)
|
if e != nil {
|
||||||
n, e := c.Read(rBuf)
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Accept() got error(%v), hanging up.", e))
|
||||||
if e != nil {
|
break
|
||||||
if e == io.EOF {
|
} else {
|
||||||
logger.LogDebug(fmt.Sprintf("lport Disconnected: shutting down tunnel [%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Accepted tunnel client %v", t))
|
||||||
} else {
|
|
||||||
logger.LogDebug(fmt.Sprintf("Read error from lport of tun [%d:%d]\n%s", lport, rport, e))
|
// outside client -> tunnel lport
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
c.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
var tunDst bytes.Buffer
|
||||||
|
binary.Write(&tunDst, binary.BigEndian, lport)
|
||||||
|
binary.Write(&tunDst, binary.BigEndian, rport)
|
||||||
|
for {
|
||||||
|
rBuf := make([]byte, 1024)
|
||||||
|
//Read data from c, encrypt/write via hc to client(lport)
|
||||||
|
n, e := c.Read(rBuf)
|
||||||
|
if e != nil {
|
||||||
|
if e == io.EOF {
|
||||||
|
logger.LogDebug(fmt.Sprintf("[ClientTun] lport Disconnected: shutting down tunnel %v", t))
|
||||||
|
} else {
|
||||||
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Read error from lport of tun %v\n%s", t, e))
|
||||||
|
}
|
||||||
|
hc.WritePacket(tunDst.Bytes(), CSOTunHangup)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if n > 0 {
|
||||||
|
rBuf = append(tunDst.Bytes(), rBuf[:n]...)
|
||||||
|
_, de := hc.WritePacket(rBuf[:n+4], CSOTunData)
|
||||||
|
if de != nil {
|
||||||
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Error writing to tunnel %v, %s]\n", t, de))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hc.WritePacket(tunDst.Bytes(), CSOTunHangup)
|
}()
|
||||||
break
|
|
||||||
}
|
|
||||||
if n > 0 {
|
|
||||||
rBuf = append(tunDst.Bytes(), rBuf[:n]...)
|
|
||||||
hc.WritePacket(rBuf[:n+4], CSOTunData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// tunnel lport -> outside client (c)
|
// tunnel lport -> outside client (c)
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
c.Close()
|
c.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
bytes, ok := <-t.Data
|
bytes, ok := <-t.Data
|
||||||
if ok {
|
if ok {
|
||||||
c.Write(bytes)
|
_, e := c.Write(bytes)
|
||||||
} else {
|
if e != nil {
|
||||||
logger.LogDebug(fmt.Sprintf("[Channel closed?]\n"))
|
logger.LogDebug(fmt.Sprintf("[ClientTun] lport conn closed"))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}()
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Channel closed?"))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
}
|
} // end Accept() worker block
|
||||||
|
} // end for-accept
|
||||||
|
} // end Listen() block
|
||||||
|
} else if cmd == 'r' {
|
||||||
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Server replied TunRefused %v\n", t))
|
||||||
|
} else if cmd == 'x' {
|
||||||
|
logger.LogDebug(fmt.Sprintf("[ClientTun] Server replied TunDisconn, closing lport %v\n", t))
|
||||||
|
l.Close()
|
||||||
|
weAreListening = false
|
||||||
}
|
}
|
||||||
}
|
} // end t.Ctl for
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *Conn) StartServerTunnel(lport, rport uint16) {
|
func (hc *Conn) StartServerTunnel(lport, rport uint16) {
|
||||||
hc.InitTunEndpoint(lport, "", rport)
|
hc.InitTunEndpoint(lport, "", rport)
|
||||||
t := hc.tuns[rport] // for convenience
|
t := (*hc.tuns)[rport] // for convenience
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
weAreDialled := false
|
||||||
for cmd := range t.Ctl {
|
for cmd := range t.Ctl {
|
||||||
var c net.Conn
|
var c net.Conn
|
||||||
if cmd == 'a' {
|
if cmd == 'd' && !weAreDialled {
|
||||||
logger.LogDebug("Server dialling...")
|
logger.LogDebug("[ServerTun] dialling...")
|
||||||
c, err = net.Dial("tcp", fmt.Sprintf(":%d", rport))
|
c, err = net.Dial("tcp", fmt.Sprintf(":%d", rport))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogDebug(fmt.Sprintf("Nothing is serving at rport :%d!", rport))
|
logger.LogDebug(fmt.Sprintf("[ServerTun] Dial() error for tun %v: %s", t, err))
|
||||||
var resp bytes.Buffer
|
var resp bytes.Buffer
|
||||||
binary.Write(&resp, binary.BigEndian /*lport*/, uint16(0))
|
binary.Write(&resp, binary.BigEndian /*lport*/, uint16(0))
|
||||||
binary.Write(&resp, binary.BigEndian, rport)
|
binary.Write(&resp, binary.BigEndian, rport)
|
||||||
hc.WritePacket(resp.Bytes(), CSOTunRefused)
|
hc.WritePacket(resp.Bytes(), CSOTunRefused)
|
||||||
} else {
|
} else {
|
||||||
logger.LogDebug(fmt.Sprintf("[Tunnel Opened - %d:%s:%d]", lport, t.Peer, rport))
|
logger.LogDebug(fmt.Sprintf("[ServerTun] Tunnel Opened - %v", t))
|
||||||
|
weAreDialled = true
|
||||||
var resp bytes.Buffer
|
var resp bytes.Buffer
|
||||||
binary.Write(&resp, binary.BigEndian, lport)
|
binary.Write(&resp, binary.BigEndian, lport)
|
||||||
binary.Write(&resp, binary.BigEndian, rport)
|
binary.Write(&resp, binary.BigEndian, rport)
|
||||||
logger.LogDebug(fmt.Sprintf("[Writing CSOTunSetupAck[%d:%d]", lport, rport))
|
logger.LogDebug(fmt.Sprintf("[ServerTun] Writing CSOTunSetupAck %v", t))
|
||||||
hc.WritePacket(resp.Bytes(), CSOTunSetupAck)
|
hc.WritePacket(resp.Bytes(), CSOTunSetupAck)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -167,7 +196,9 @@ func (hc *Conn) StartServerTunnel(lport, rport uint16) {
|
||||||
//
|
//
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
logger.LogDebug("[ServerTun] (deferred hangup workerA)")
|
||||||
c.Close()
|
c.Close()
|
||||||
|
weAreDialled = false
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var tunDst bytes.Buffer
|
var tunDst bytes.Buffer
|
||||||
|
@ -179,15 +210,15 @@ func (hc *Conn) StartServerTunnel(lport, rport uint16) {
|
||||||
n, e := c.Read(rBuf)
|
n, e := c.Read(rBuf)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
if e == io.EOF {
|
if e == io.EOF {
|
||||||
logger.LogDebug(fmt.Sprintf("rport Disconnected: shutting down tunnel %v\n", t))
|
logger.LogDebug(fmt.Sprintf("[ServerTun] rport Disconnected: shutting down tunnel %v", t))
|
||||||
} else {
|
} else {
|
||||||
logger.LogDebug(fmt.Sprintf("Read error from rport of tun %v\n%s", t, e))
|
logger.LogDebug(fmt.Sprintf("[ServerTun] Read error from rport of tun %v: %s", t, e))
|
||||||
}
|
}
|
||||||
var resp bytes.Buffer
|
var resp bytes.Buffer
|
||||||
binary.Write(&resp, binary.BigEndian, lport)
|
binary.Write(&resp, binary.BigEndian, lport)
|
||||||
binary.Write(&resp, binary.BigEndian, rport)
|
binary.Write(&resp, binary.BigEndian, rport)
|
||||||
hc.WritePacket(resp.Bytes(), CSOTunDisconn)
|
hc.WritePacket(resp.Bytes(), CSOTunDisconn)
|
||||||
logger.LogDebug(fmt.Sprintf("Closing server rport %d net.Dial()", t.Rport))
|
logger.LogDebug(fmt.Sprintf("[ServerTun] Closing server rport %d net.Dial()", t.Rport))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
|
@ -200,22 +231,32 @@ func (hc *Conn) StartServerTunnel(lport, rport uint16) {
|
||||||
// worker to read data from client (already decrypted) & fwd to rport
|
// worker to read data from client (already decrypted) & fwd to rport
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
logger.LogDebug("[ServerTun] (deferred hangup workerB)")
|
||||||
c.Close()
|
c.Close()
|
||||||
|
weAreDialled = false
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
rData, ok := <-t.Data
|
rData, ok := <-t.Data
|
||||||
if ok {
|
if ok {
|
||||||
c.Write(rData)
|
_, e := c.Write(rData)
|
||||||
|
if e != nil {
|
||||||
|
logger.LogDebug(fmt.Sprintf("[ServerTun] ERROR writing to rport conn"))
|
||||||
|
break
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.LogDebug("[ERROR reading from hc.tuns[] channel - closed?]")
|
logger.LogDebug("[ServerTun] ERROR reading from hc.tuns[] channel - closed?")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
} // TODO: elseifs for other state transtions driven by client
|
} else if cmd == 'h' {
|
||||||
}
|
// client side has hung up
|
||||||
}() // t.Ctl read loop
|
logger.LogDebug(fmt.Sprintf("[ServerTun] Client hung up: hanging up on rport %v", t))
|
||||||
logger.LogDebug("[ServerTunnel() exiting t.Ctl read loop - channel closed??]")
|
weAreDialled = false
|
||||||
|
}
|
||||||
|
} // t.Ctl read loop
|
||||||
|
logger.LogDebug("[ServerTun] Tunnel exiting t.Ctl read loop - channel closed??")
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,25 +350,6 @@ func reqTunnel(hc *hkexnet.Conn, lp uint16, p string /*net.Addr*/, rp uint16) {
|
||||||
logger.LogDebug(fmt.Sprintln("[Client sending CSOTunSetup]"))
|
logger.LogDebug(fmt.Sprintln("[Client sending CSOTunSetup]"))
|
||||||
hc.WritePacket(bTmp.Bytes(), hkexnet.CSOTunSetup)
|
hc.WritePacket(bTmp.Bytes(), hkexnet.CSOTunSetup)
|
||||||
|
|
||||||
// Server should reply immediately with CSOTunSetupAck[lport:rport]
|
|
||||||
// hkexnet.Read() on server side handles server side tun setup.
|
|
||||||
resp := make([]byte, 4)
|
|
||||||
var lpResp, rpResp uint16
|
|
||||||
n, e := io.ReadFull(hc, resp)
|
|
||||||
if n < 4 || e != nil {
|
|
||||||
logger.LogErr(fmt.Sprintf("[Client tun response len %d, %s\n", n, e))
|
|
||||||
} else {
|
|
||||||
lpResp = binary.BigEndian.Uint16(resp[0:2])
|
|
||||||
rpResp = binary.BigEndian.Uint16(resp[2:4])
|
|
||||||
}
|
|
||||||
|
|
||||||
if lpResp == lp && rpResp == rp {
|
|
||||||
logger.LogDebug("[Client got tun setup ack OK]")
|
|
||||||
hc.StartClientTunnel(lp, rp)
|
|
||||||
} else {
|
|
||||||
logger.LogDebug(fmt.Sprintf("[Client tun response ports [%d:%d]\n", lpResp, rpResp))
|
|
||||||
logger.LogDebug(fmt.Sprintln("[Client tun setup FAILED]"))
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue