forked from nadoo/glider
-
Notifications
You must be signed in to change notification settings - Fork 0
/
conn.go
96 lines (80 loc) · 1.87 KB
/
conn.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package conn
import (
"bufio"
"io"
"net"
"time"
)
// UDPBufSize is the size of udp buffer
const UDPBufSize = 65536
// Conn struct
type Conn struct {
r *bufio.Reader
net.Conn
}
// NewConn .
func NewConn(c net.Conn) *Conn {
return &Conn{bufio.NewReader(c), c}
}
// NewConnSize .
func NewConnSize(c net.Conn, n int) *Conn {
return &Conn{bufio.NewReaderSize(c, n), c}
}
// Peek .
func (c *Conn) Peek(n int) ([]byte, error) {
return c.r.Peek(n)
}
// Read .
func (c *Conn) Read(p []byte) (int, error) {
return c.r.Read(p)
}
// Reader returns the internal bufio.Reader
func (c *Conn) Reader() *bufio.Reader {
return c.r
}
// Relay .
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
}
// TimedCopy copy from src to dst at target with read timeout
func TimedCopy(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout time.Duration) error {
buf := make([]byte, UDPBufSize)
for {
src.SetReadDeadline(time.Now().Add(timeout))
n, _, err := src.ReadFrom(buf)
if err != nil {
return err
}
_, err = dst.WriteTo(buf[:n], target)
if err != nil {
return err
}
}
}
// OutboundIP returns preferred outbound ip of this machine
func OutboundIP() string {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
return ""
}
defer conn.Close()
return conn.LocalAddr().(*net.UDPAddr).IP.String()
}