mirror of
https://github.com/openp2p-cn/openp2p.git
synced 2025-12-24 12:57:52 +08:00
86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
// implement io.Writer
|
|
type overlayTCP struct {
|
|
tunnel *P2PTunnel
|
|
conn net.Conn
|
|
id uint64
|
|
rtid uint64
|
|
running bool
|
|
isClient bool
|
|
appID uint64
|
|
appKey uint64
|
|
appKeyBytes []byte
|
|
}
|
|
|
|
func (otcp *overlayTCP) run() {
|
|
gLog.Printf(LevelINFO, "%d overlayTCP run start", otcp.id)
|
|
defer gLog.Printf(LevelINFO, "%d overlayTCP run end", otcp.id)
|
|
otcp.running = true
|
|
buffer := make([]byte, ReadBuffLen+PaddingSize)
|
|
readBuf := buffer[:ReadBuffLen]
|
|
encryptData := make([]byte, ReadBuffLen+PaddingSize) // 16 bytes for padding
|
|
tunnelHead := new(bytes.Buffer)
|
|
relayHead := new(bytes.Buffer)
|
|
binary.Write(relayHead, binary.LittleEndian, otcp.rtid)
|
|
binary.Write(tunnelHead, binary.LittleEndian, otcp.id)
|
|
for otcp.running && otcp.tunnel.isRuning() {
|
|
otcp.conn.SetReadDeadline(time.Now().Add(time.Second * 5))
|
|
dataLen, err := otcp.conn.Read(readBuf)
|
|
if err != nil {
|
|
if ne, ok := err.(net.Error); ok && ne.Timeout() {
|
|
continue
|
|
}
|
|
// overlay tcp connection normal close, debug log
|
|
gLog.Printf(LevelDEBUG, "overlayTCP %d read error:%s,close it", otcp.id, err)
|
|
break
|
|
} else {
|
|
payload := readBuf[:dataLen]
|
|
if otcp.appKey != 0 {
|
|
payload, _ = encryptBytes(otcp.appKeyBytes, encryptData, buffer[:dataLen], dataLen)
|
|
}
|
|
writeBytes := append(tunnelHead.Bytes(), payload...)
|
|
if otcp.rtid == 0 {
|
|
otcp.tunnel.conn.WriteBytes(MsgP2P, MsgOverlayData, writeBytes)
|
|
} else {
|
|
// write raley data
|
|
all := append(relayHead.Bytes(), encodeHeader(MsgP2P, MsgOverlayData, uint32(len(writeBytes)))...)
|
|
all = append(all, writeBytes...)
|
|
otcp.tunnel.conn.WriteBytes(MsgP2P, MsgRelayData, all)
|
|
gLog.Printf(LevelDEBUG, "write relay data to %d:%d bodylen=%d", otcp.rtid, otcp.id, len(writeBytes))
|
|
}
|
|
}
|
|
}
|
|
otcp.conn.Close()
|
|
otcp.tunnel.overlayConns.Delete(otcp.id)
|
|
// notify peer disconnect
|
|
if otcp.isClient {
|
|
req := OverlayDisconnectReq{ID: otcp.id}
|
|
if otcp.rtid == 0 {
|
|
otcp.tunnel.conn.WriteMessage(MsgP2P, MsgOverlayDisconnectReq, &req)
|
|
} else {
|
|
// write relay data
|
|
msg, _ := newMessage(MsgP2P, MsgOverlayDisconnectReq, &req)
|
|
msgWithHead := append(relayHead.Bytes(), msg...)
|
|
otcp.tunnel.conn.WriteBytes(MsgP2P, MsgRelayData, msgWithHead)
|
|
}
|
|
}
|
|
}
|
|
|
|
// calling by p2pTunnel
|
|
func (otcp *overlayTCP) Write(buff []byte) (n int, err error) {
|
|
// add mutex when multi-thread calling
|
|
n, err = otcp.conn.Write(buff)
|
|
if err != nil {
|
|
otcp.tunnel.overlayConns.Delete(otcp.id)
|
|
}
|
|
return
|
|
}
|