代码拉取完成,页面将自动刷新
package courier
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"gitee.com/dongmingchao/decent-ft/src/caretaker"
"gitee.com/dongmingchao/decent-ft/src/event"
resourcePool "gitee.com/dongmingchao/decent-ft/src/resource-pool"
"gitee.com/dongmingchao/decent-ft/src/utils"
"log"
"net"
"os"
"os/signal"
"syscall"
"time"
)
//import "github.com/thoas/go-funk"
func freePort() *net.UDPAddr {
raddr, _ := net.ResolveUDPAddr("udp", "8.8.8.8:22")
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
defer func() {
_ = conn.Close()
}()
laddr, _ := net.ResolveUDPAddr("udp", conn.LocalAddr().String())
return laddr
}
type Op byte
const (
Done Op = 1 + iota
AskIndex
Get
Connect
TCP
Pass
Search
Update
Bypass
Remove
Patch
)
func GetIndexInfo(rAddr *net.UDPAddr) resourcePool.GTree {
buf := remoteCall(rAddr, AskIndex, nil)
stash := resourcePool.GTree{}
stash.Read(bytes.NewReader(buf))
return stash
}
func GetFileContent(rAddr *utils.UDPAddr, hash [20]byte) *bytes.Buffer {
buf := remoteCall(rAddr.UDPAddr, Get, func(conn *net.UDPConn) []byte {
return hash[:]
})
return bytes.NewBuffer(buf)
}
func ConnectNeighbor(rAddr *net.UDPAddr) []byte {
var sent bytes.Buffer
return remoteCall(rAddr, Connect, func(conn *net.UDPConn) []byte {
err := conn.SetDeadline(time.Now().Add(time.Second))
if err != nil {
fmt.Println("Connect Deadline", err)
}
srcAddr, _ := net.ResolveUDPAddr("udp", conn.LocalAddr().String())
srcAddr.Port = poolAddr.Port
addr := utils.NewUDPAddr(srcAddr)
addr.Write(&sent)
caretaker.GlobalStash.Write(&sent)
return sent.Bytes()
})
}
func remoteCall(rAddr *net.UDPAddr, code Op, rest func(*net.UDPConn) []byte) []byte {
conn := makeConn(rAddr)
data := []byte{byte(code)}
if rest != nil {
data = append(data, rest(conn)...)
}
SendData(conn, data)
buf := recv(conn, code)
err := conn.Close()
if err != nil {
log.Fatalln("remoteCall close error", err)
}
return buf
}
//func localCall(rAddr utils.UDPAddr, rest func(*net.UDPConn) []byte) {
// data := []byte{byte(Pass)}
// SilentSend(rAddr, func(conn *net.UDPConn) []byte {
// if rest != nil {
// data = append(data, rest(conn)...)
// }
// return data
// })
//}
func SendData(conn *net.UDPConn, ask []byte) {
_, err := conn.Write(ask)
if err != nil {
log.Fatalln("Send Data", err)
}
}
func makeConn(rAddr *net.UDPAddr) *net.UDPConn {
conn, err := net.DialUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0}, rAddr)
if err != nil {
log.Fatalln("makeConn", err)
}
return conn
}
//func Send(rAddr *net.UDPAddr, ask []byte) *net.UDPConn {
// conn := makeConn(rAddr)
// SendData(conn, ask)
// return conn
//}
func SilentSend(rAddr utils.UDPAddr, data func(*net.UDPConn) []byte) {
conn := makeConn(rAddr.UDPAddr)
SendData(conn, data(conn))
err := conn.Close()
if err != nil {
log.Fatal(err)
}
}
type Response struct {
length uint16
code Op
reader *bufio.Reader
conn net.Conn
}
func presetRead(conn net.Conn) (Response, error) {
reader := bufio.NewReader(conn)
lengthBuf := make([]byte, 2)
_, err := reader.Read(lengthBuf)
if err != nil {
fmt.Println("presetRead read error", err)
return Response{}, err
}
length := binary.BigEndian.Uint16(lengthBuf)
bakCode, err := reader.ReadByte()
if err != nil {
log.Fatal(err)
}
return Response{
length,
Op(bakCode),
reader,
conn,
}, nil
}
func recv(conn net.Conn, askCode Op) []byte {
resp, err := presetRead(conn)
if err != nil {
return nil
}
for _, mw := range feedbackMiddleWares {
ret := mw(askCode, resp)
if ret != nil {
return ret
}
}
println("panic, response not be handled")
return nil
}
var poolAddr *net.UDPAddr
func Start(wg event.Bus) {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
var conn *net.UDPConn
var err error
go func() {
feedbackMiddleWares = append(feedbackMiddleWares, simpleShow, handleConnect)
lAddr, err := net.ResolveUDPAddr("udp", ":0")
if err != nil {
log.Fatalln("Find Port Error")
}
conn, err = net.ListenUDP("udp", lAddr)
if err != nil {
fmt.Println("ListenUDP err:", err)
return
}
poolAddr, err = net.ResolveUDPAddr("udp", conn.LocalAddr().String())
if err != nil {
log.Fatalln("pool addr resolve error")
}
fmt.Println("local addr: ", poolAddr)
for {
readBuf := make([]byte, 0xffff+2) // TODO: 判断超出最大
n, rAddr, err := conn.ReadFromUDP(readBuf)
if err != nil {
// connect closed because of ctrl-c
log.Printf("Because of Shutdown, %v", err)
break
}
reader := bufio.NewReader(bytes.NewReader(readBuf))
buf := handleListen(reader, rAddr)
if len(buf) == 0 {
continue
}
n, err = conn.WriteTo(finalResponse(buf), rAddr)
if err != nil {
log.Fatal(err)
}
println("remote addr: ", rAddr.String())
println("msg length: ", n)
//fmt.Println("msg content", buf)
println("feed back finish: ", rAddr.String())
}
}()
go func() {
bridgeAddr, err := net.ResolveTCPAddr("tcp", ":0")
if err != nil {
log.Fatalln("TCP Find Port Error")
}
BridgeListen(bridgeAddr)
}()
wg.Emit("courier-ready")
<-sigs
err = conn.Close()
if err != nil {
log.Fatal(err)
}
defer wg.Emit("stop-courier")
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。