mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-08-04 12:55:17 +03:00
Add OpenVPN, TrustTunnel, Sudoku, inbound managers. Fixes
This commit is contained in:
174
transport/trusttunnel/protocol.go
Normal file
174
transport/trusttunnel/protocol.go
Normal file
@@ -0,0 +1,174 @@
|
||||
package trusttunnel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
UDPMagicAddress = "_udp2"
|
||||
ICMPMagicAddress = "_icmp"
|
||||
HealthCheckMagicAddress = "_check"
|
||||
DefaultConnectionTimeout = 30 * time.Second
|
||||
DefaultHealthCheckTimeout = 7 * time.Second
|
||||
DefaultSessionTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
func buildAuth(username string, password string) string {
|
||||
return "Basic " + base64.StdEncoding.EncodeToString([]byte(username+":"+password))
|
||||
}
|
||||
|
||||
func parseBasicAuth(auth string) (username, password string, ok bool) {
|
||||
const prefix = "Basic "
|
||||
if len(auth) < len(prefix) || !strings.EqualFold(auth[:len(prefix)], prefix) {
|
||||
return "", "", false
|
||||
}
|
||||
c, err := base64.StdEncoding.DecodeString(auth[len(prefix):])
|
||||
if err != nil {
|
||||
return "", "", false
|
||||
}
|
||||
cs := string(c)
|
||||
username, password, ok = strings.Cut(cs, ":")
|
||||
return
|
||||
}
|
||||
|
||||
func parse16BytesIP(buffer [16]byte) netip.Addr {
|
||||
var zeroPrefix [12]byte
|
||||
isIPv4 := bytes.HasPrefix(buffer[:], zeroPrefix[:])
|
||||
isIPv4 = isIPv4 && !(buffer[12] == 0 && buffer[13] == 0 && buffer[14] == 0 && buffer[15] == 1)
|
||||
if isIPv4 {
|
||||
return netip.AddrFrom4([4]byte(buffer[12:16]))
|
||||
}
|
||||
return netip.AddrFrom16(buffer)
|
||||
}
|
||||
|
||||
func buildPaddingIP(addr netip.Addr) (buffer [16]byte) {
|
||||
if addr.Is6() {
|
||||
return addr.As16()
|
||||
}
|
||||
ipv4 := addr.As4()
|
||||
copy(buffer[12:16], ipv4[:])
|
||||
return buffer
|
||||
}
|
||||
|
||||
type httpConn struct {
|
||||
writer io.Writer
|
||||
flusher http.Flusher
|
||||
body io.ReadCloser
|
||||
setupOnce sync.Once
|
||||
created chan struct{}
|
||||
createErr error
|
||||
cancelFn func()
|
||||
closeFn func()
|
||||
remoteAddr net.Addr
|
||||
localAddr net.Addr
|
||||
deadline *time.Timer
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func (h *httpConn) setup(body io.ReadCloser, err error) {
|
||||
h.setupOnce.Do(func() {
|
||||
h.body = body
|
||||
h.createErr = err
|
||||
close(h.created)
|
||||
})
|
||||
if h.createErr != nil && body != nil {
|
||||
_ = body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (h *httpConn) waitCreated() error {
|
||||
<-h.created
|
||||
if h.body != nil {
|
||||
return nil
|
||||
}
|
||||
return h.createErr
|
||||
}
|
||||
|
||||
func (h *httpConn) Close() error {
|
||||
h.setup(nil, net.ErrClosed)
|
||||
if closer, ok := h.writer.(io.Closer); ok {
|
||||
_ = closer.Close()
|
||||
}
|
||||
if h.body != nil {
|
||||
_ = h.body.Close()
|
||||
}
|
||||
if h.cancelFn != nil {
|
||||
h.cancelFn()
|
||||
}
|
||||
if h.closeFn != nil {
|
||||
h.closeFn()
|
||||
}
|
||||
if h.done != nil {
|
||||
select {
|
||||
case <-h.done:
|
||||
default:
|
||||
close(h.done)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *httpConn) writeFlush(p []byte) (n int, err error) {
|
||||
n, err = h.writer.Write(p)
|
||||
if h.flusher != nil {
|
||||
h.flusher.Flush()
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (h *httpConn) RemoteAddr() net.Addr {
|
||||
if h.remoteAddr != nil {
|
||||
return h.remoteAddr
|
||||
}
|
||||
return &net.TCPAddr{}
|
||||
}
|
||||
|
||||
func (h *httpConn) LocalAddr() net.Addr {
|
||||
if h.localAddr != nil {
|
||||
return h.localAddr
|
||||
}
|
||||
return &net.TCPAddr{}
|
||||
}
|
||||
|
||||
func (h *httpConn) SetDeadline(t time.Time) error {
|
||||
if t.IsZero() {
|
||||
if h.deadline != nil {
|
||||
h.deadline.Stop()
|
||||
h.deadline = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
d := time.Until(t)
|
||||
if h.deadline != nil {
|
||||
h.deadline.Reset(d)
|
||||
return nil
|
||||
}
|
||||
h.deadline = time.AfterFunc(d, func() { h.Close() })
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *httpConn) SetReadDeadline(t time.Time) error { return h.SetDeadline(t) }
|
||||
func (h *httpConn) SetWriteDeadline(t time.Time) error { return h.SetDeadline(t) }
|
||||
|
||||
var _ net.Conn = (*tcpConn)(nil)
|
||||
|
||||
type tcpConn struct{ httpConn }
|
||||
|
||||
func (t *tcpConn) Read(b []byte) (n int, err error) {
|
||||
if err = t.waitCreated(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return t.body.Read(b)
|
||||
}
|
||||
|
||||
func (t *tcpConn) Write(b []byte) (int, error) {
|
||||
return t.writeFlush(b)
|
||||
}
|
||||
Reference in New Issue
Block a user