forked from gopwn/pwn
-
Notifications
You must be signed in to change notification settings - Fork 1
/
net.go
122 lines (99 loc) · 2.7 KB
/
net.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package pwn
import (
"net"
"sync"
)
// A Listener is a generic network listener for stream-oriented protocols.
// Multiple goroutines may invoke methods on a Listener simultaneously.
type Listener interface {
// Accept waits for and returns the next Connection to the listener.
Accept() (Conn, error)
// Close closes the listener.
// Any blocked Accept operations will be unblocked and return errors.
Close() error
// Addr returns the listener's network address.
Addr() net.Addr
}
type listener struct {
l net.Listener
}
func (l listener) Addr() net.Addr {
return l.l.Addr()
}
func (l listener) Close() error {
return l.l.Close()
}
func (l listener) Accept() (Conn, error) {
rawConn, err := l.l.Accept()
if err != nil {
return Conn{}, err
}
return Conn{
rawConn,
// the default line length to be used with Conn.ReadLine
MaxLenDefault,
sync.Mutex{},
}, nil
}
// Conn is a generic stream-oriented network connection.
//
// Multiple goroutines may invoke methods on a Conn simultaneously.
type Conn struct {
// the embeedded net.Conn
net.Conn
// the max length for ReadLine and ReadTill.
maxLen int
// mu is used for protecting struct variables from concurrent reads / writes
mu sync.Mutex
}
// MaxLen changes the max length for ReadLine and ReadTill in the conn
func (c *Conn) MaxLen(length int) {
// prevent panics
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.maxLen = length
}
// ReadLine reads until '\n' and returns bytes read and possible error.
func (c *Conn) ReadLine() ([]byte, error) {
return ReadTill(c, c.maxLen, '\n')
}
// ReadTill reads till 'delim' and returns bytes read and possible error.
func (c *Conn) ReadTill(delim byte) ([]byte, error) {
return ReadTill(c, c.maxLen, delim)
}
// WriteLine writes a line to the Connection.
// t can be anything convertable to []byte (see Bytes function)
// Bytes will panic if it fails to convert to []byte
func (c *Conn) WriteLine(t interface{}) error {
return WriteLine(c, t)
}
// Dial creates a new network Connection returning a Conn,
// MaxLineLength is by default set to MaxLenDefault, you can change it in the returned
// Conn using Conn.MaxLen(i int).
func Dial(network, addr string) (Conn, error) {
rawConn, err := net.Dial(network, addr)
if err != nil {
return Conn{}, err
}
return Conn{
rawConn,
// the default line length to be used with Conn.ReadLine
MaxLenDefault,
// mutex to protect concurrent calls
sync.Mutex{},
}, nil
}
// Listen creates a net.Listener that will accept Connections
// and wrap them in a pwn.Conn
func Listen(network, addr string) (Listener, error) {
rawListener, err := net.Listen(network, addr)
if err != nil {
return nil, err
}
return listener{
l: rawListener,
}, nil
}