glider/conn.go

96 lines
2.0 KiB
Go
Raw Normal View History

2017-07-13 21:55:41 +08:00
package main
import (
"bufio"
"io"
"log"
2017-07-13 21:55:41 +08:00
"net"
"time"
)
type conn struct {
r *bufio.Reader
net.Conn
}
func newConn(c net.Conn) conn {
return conn{bufio.NewReader(c), c}
}
func newConnSize(c net.Conn, n int) conn {
return conn{bufio.NewReaderSize(c, n), c}
}
func (c conn) Peek(n int) ([]byte, error) {
return c.r.Peek(n)
}
func (c conn) Read(p []byte) (int, error) {
return c.r.Read(p)
}
func relay(left, right net.Conn) (int64, int64, error) {
type res struct {
N int64
Err error
}
ch := make(chan res)
go func() {
n, err := io.Copy(right, left)
right.SetDeadline(time.Now()) // wake up the other goroutine blocking on right
left.SetDeadline(time.Now()) // wake up the other goroutine blocking on left
ch <- res{n, err}
}()
n, err := io.Copy(left, right)
right.SetDeadline(time.Now()) // wake up the other goroutine blocking on right
left.SetDeadline(time.Now()) // wake up the other goroutine blocking on left
rs := <-ch
if err == nil {
err = rs.Err
}
return n, rs.N, err
}
2018-01-08 18:14:57 +08:00
// copy from src to dst at target with read timeout
func timedCopy(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout time.Duration, srcIncluded bool) error {
buf := make([]byte, udpBufSize)
for {
src.SetReadDeadline(time.Now().Add(timeout))
n, raddr, err := src.ReadFrom(buf)
if err != nil {
return err
}
if srcIncluded { // server -> client: add original packet source
srcAddr := ParseAddr(raddr.String())
copy(buf[len(srcAddr):], buf[:n])
copy(buf, srcAddr)
_, err = dst.WriteTo(buf[:len(srcAddr)+n], target)
} else { // client -> user: strip original packet source
srcAddr := SplitAddr(buf[:n])
_, err = dst.WriteTo(buf[len(srcAddr):n], target)
}
if err != nil {
return err
}
}
}
// OutboundIP returns preferred outbound ip of this machine
func OutboundIP() net.IP {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP
}