2 // initial handshake. |
2 // initial handshake. |
3 |
3 |
4 package xmpp |
4 package xmpp |
5 |
5 |
6 import ( |
6 import ( |
|
7 "crypto/tls" |
7 "io" |
8 "io" |
8 "net" |
9 "net" |
9 "time" |
10 "time" |
10 ) |
11 ) |
11 |
12 |
12 func (cl *Client) recvTransport(w io.WriteCloser) { |
13 var l1interval = time.Second |
|
14 |
|
15 type layer1 struct { |
|
16 sock net.Conn |
|
17 recvSocks chan<- net.Conn |
|
18 sendSocks chan net.Conn |
|
19 } |
|
20 |
|
21 func startLayer1(sock net.Conn, recvWriter io.WriteCloser, |
|
22 sendReader io.ReadCloser) *layer1 { |
|
23 l1 := layer1{sock: sock} |
|
24 recvSocks := make(chan net.Conn) |
|
25 l1.recvSocks = recvSocks |
|
26 sendSocks := make(chan net.Conn, 1) |
|
27 l1.sendSocks = sendSocks |
|
28 go recvTransport(recvSocks, recvWriter) |
|
29 go sendTransport(sendSocks, sendReader) |
|
30 recvSocks <- sock |
|
31 sendSocks <- sock |
|
32 return &l1 |
|
33 } |
|
34 |
|
35 func (l1 *layer1) startTls(conf *tls.Config) { |
|
36 sendSockToSender := func(sock net.Conn) { |
|
37 for { |
|
38 select { |
|
39 case <-l1.sendSocks: |
|
40 case l1.sendSocks <- sock: |
|
41 return |
|
42 } |
|
43 } |
|
44 } |
|
45 |
|
46 sendSockToSender(nil) |
|
47 l1.recvSocks <- nil |
|
48 l1.sock = tls.Client(l1.sock, conf) |
|
49 sendSockToSender(l1.sock) |
|
50 l1.recvSocks <- l1.sock |
|
51 } |
|
52 |
|
53 func recvTransport(socks <-chan net.Conn, w io.WriteCloser) { |
13 defer w.Close() |
54 defer w.Close() |
|
55 var sock net.Conn |
14 p := make([]byte, 1024) |
56 p := make([]byte, 1024) |
15 for { |
57 for { |
16 if cl.socket == nil { |
58 select { |
17 cl.waitForSocket() |
59 case sock = <-socks: |
|
60 default: |
18 } |
61 } |
19 cl.socket.SetReadDeadline(time.Now().Add(time.Second)) |
62 |
20 nr, err := cl.socket.Read(p) |
63 if sock == nil { |
21 if nr == 0 { |
64 time.Sleep(l1interval) |
22 if errno, ok := err.(*net.OpError); ok { |
65 } else { |
23 if errno.Timeout() { |
66 sock.SetReadDeadline(time.Now().Add(l1interval)) |
24 continue |
67 nr, err := sock.Read(p) |
|
68 if nr == 0 { |
|
69 if errno, ok := err.(*net.OpError); ok { |
|
70 if errno.Timeout() { |
|
71 continue |
|
72 } |
25 } |
73 } |
|
74 Warn.Logf("recvTransport: %s", err) |
|
75 break |
26 } |
76 } |
27 Warn.Logf("read: %s", err) |
77 nw, err := w.Write(p[:nr]) |
28 break |
78 if nw < nr { |
29 } |
79 Warn.Logf("recvTransport: %s", err) |
30 nw, err := w.Write(p[:nr]) |
80 break |
31 if nw < nr { |
81 } |
32 Warn.Logf("read: %s", err) |
|
33 break |
|
34 } |
82 } |
35 } |
83 } |
36 } |
84 } |
37 |
85 |
38 func (cl *Client) sendTransport(r io.Reader) { |
86 func sendTransport(socks <-chan net.Conn, r io.Reader) { |
39 defer cl.socket.Close() |
87 var sock net.Conn |
40 p := make([]byte, 1024) |
88 p := make([]byte, 1024) |
41 for { |
89 for { |
42 nr, err := r.Read(p) |
90 nr, err := r.Read(p) |
43 if nr == 0 { |
91 if nr == 0 { |
44 Warn.Logf("write: %s", err) |
92 Warn.Logf("sendTransport: %s", err) |
45 break |
93 break |
46 } |
94 } |
47 nw, err := cl.socket.Write(p[:nr]) |
95 for nr > 0 { |
48 if nw < nr { |
96 select { |
49 Warn.Logf("write: %s", err) |
97 case sock = <-socks: |
50 break |
98 if sock != nil { |
|
99 defer sock.Close() |
|
100 } |
|
101 default: |
|
102 } |
|
103 |
|
104 if sock == nil { |
|
105 time.Sleep(l1interval) |
|
106 } else { |
|
107 nw, err := sock.Write(p[:nr]) |
|
108 nr -= nw |
|
109 if nr != 0 { |
|
110 Warn.Logf("write: %s", err) |
|
111 break |
|
112 } |
|
113 } |
51 } |
114 } |
52 } |
115 } |
53 } |
116 } |