|
@@ -10,9 +10,11 @@ import (
|
10
|
10
|
"crypto/tls"
|
11
|
11
|
"encoding/hex"
|
12
|
12
|
"errors"
|
|
13
|
+ "fmt"
|
13
|
14
|
"io"
|
14
|
15
|
"net"
|
15
|
16
|
"strings"
|
|
17
|
+ "sync"
|
16
|
18
|
"time"
|
17
|
19
|
)
|
18
|
20
|
|
|
@@ -27,23 +29,25 @@ type Socket struct {
|
27
|
29
|
Closed bool
|
28
|
30
|
conn net.Conn
|
29
|
31
|
reader *bufio.Reader
|
|
32
|
+
|
|
33
|
+ lineToSendExists chan bool
|
|
34
|
+ linesToSend []string
|
|
35
|
+ linesToSendMutex sync.Mutex
|
30
|
36
|
}
|
31
|
37
|
|
32
|
38
|
// NewSocket returns a new Socket.
|
33
|
39
|
func NewSocket(conn net.Conn) Socket {
|
34
|
40
|
return Socket{
|
35
|
|
- conn: conn,
|
36
|
|
- reader: bufio.NewReader(conn),
|
|
41
|
+ conn: conn,
|
|
42
|
+ reader: bufio.NewReader(conn),
|
|
43
|
+ lineToSendExists: make(chan bool),
|
37
|
44
|
}
|
38
|
45
|
}
|
39
|
46
|
|
40
|
47
|
// Close stops a Socket from being able to send/receive any more data.
|
41
|
48
|
func (socket *Socket) Close() {
|
42
|
|
- if socket.Closed {
|
43
|
|
- return
|
44
|
|
- }
|
45
|
49
|
socket.Closed = true
|
46
|
|
- socket.conn.Close()
|
|
50
|
+ // socket will close once all data has been sent
|
47
|
51
|
}
|
48
|
52
|
|
49
|
53
|
// CertFP returns the fingerprint of the certificate provided by the client.
|
|
@@ -104,15 +108,57 @@ func (socket *Socket) Write(data string) error {
|
104
|
108
|
return io.EOF
|
105
|
109
|
}
|
106
|
110
|
|
107
|
|
- // write data
|
108
|
|
- _, err := socket.conn.Write([]byte(data))
|
109
|
|
- if err != nil {
|
110
|
|
- socket.Close()
|
111
|
|
- return err
|
112
|
|
- }
|
|
111
|
+ socket.linesToSendMutex.Lock()
|
|
112
|
+ socket.linesToSend = append(socket.linesToSend, data)
|
|
113
|
+ socket.linesToSendMutex.Unlock()
|
|
114
|
+ go socket.fillLineToSendExists()
|
|
115
|
+
|
113
|
116
|
return nil
|
114
|
117
|
}
|
115
|
118
|
|
|
119
|
+// fillLineToSendExists only exists because you can't goroutine single statements.
|
|
120
|
+func (socket *Socket) fillLineToSendExists() {
|
|
121
|
+ socket.lineToSendExists <- true
|
|
122
|
+}
|
|
123
|
+
|
|
124
|
+// RunSocketWriter starts writing messages to the outgoing socket.
|
|
125
|
+func (socket *Socket) RunSocketWriter() {
|
|
126
|
+ var errOut bool
|
|
127
|
+ for {
|
|
128
|
+ // wait for new lines
|
|
129
|
+ select {
|
|
130
|
+ case <-socket.lineToSendExists:
|
|
131
|
+ socket.linesToSendMutex.Lock()
|
|
132
|
+
|
|
133
|
+ // get data
|
|
134
|
+ data := socket.linesToSend[0]
|
|
135
|
+ if len(socket.linesToSend) > 1 {
|
|
136
|
+ socket.linesToSend = socket.linesToSend[1:]
|
|
137
|
+ } else {
|
|
138
|
+ socket.linesToSend = []string{}
|
|
139
|
+ }
|
|
140
|
+
|
|
141
|
+ // write data
|
|
142
|
+ _, err := socket.conn.Write([]byte(data))
|
|
143
|
+ if err != nil {
|
|
144
|
+ errOut = true
|
|
145
|
+ fmt.Println(err.Error())
|
|
146
|
+ break
|
|
147
|
+ }
|
|
148
|
+ socket.linesToSendMutex.Unlock()
|
|
149
|
+ }
|
|
150
|
+ if errOut {
|
|
151
|
+ // error out, bad stuff happened
|
|
152
|
+ break
|
|
153
|
+ }
|
|
154
|
+ }
|
|
155
|
+ //TODO(dan): empty socket.lineToSendExists queue
|
|
156
|
+ socket.conn.Close()
|
|
157
|
+ if !socket.Closed {
|
|
158
|
+ socket.Closed = true
|
|
159
|
+ }
|
|
160
|
+}
|
|
161
|
+
|
116
|
162
|
// WriteLine writes the given line out of Socket.
|
117
|
163
|
func (socket *Socket) WriteLine(line string) error {
|
118
|
164
|
return socket.Write(line + "\r\n")
|