3 |
3 |
4 package xmpp |
4 package xmpp |
5 |
5 |
6 import ( |
6 import ( |
7 "crypto/tls" |
7 "crypto/tls" |
|
8 "fmt" |
8 "io" |
9 "io" |
|
10 "log" |
9 "net" |
11 "net" |
10 "time" |
12 "time" |
11 ) |
13 ) |
|
14 |
|
15 // If enabled, print all sent and received XML. |
|
16 var Debug = false |
12 |
17 |
13 var l1interval = time.Second |
18 var l1interval = time.Second |
14 |
19 |
15 type layer1 struct { |
20 type layer1 struct { |
16 sock net.Conn |
21 sock net.Conn |
17 recvSocks chan<- net.Conn |
22 recvSocks chan<- net.Conn |
18 sendSocks chan net.Conn |
23 sendSocks chan net.Conn |
19 } |
24 } |
20 |
25 |
21 func startLayer1(sock net.Conn, recvWriter io.WriteCloser, |
26 func (cl *Client) startLayer1(sock net.Conn, recvWriter io.WriteCloser, |
22 sendReader io.ReadCloser, status <-chan Status) *layer1 { |
27 sendReader io.ReadCloser, status <-chan Status) *layer1 { |
23 l1 := layer1{sock: sock} |
28 l1 := layer1{sock: sock} |
24 recvSocks := make(chan net.Conn) |
29 recvSocks := make(chan net.Conn) |
25 l1.recvSocks = recvSocks |
30 l1.recvSocks = recvSocks |
26 sendSocks := make(chan net.Conn, 1) |
31 sendSocks := make(chan net.Conn, 1) |
27 l1.sendSocks = sendSocks |
32 l1.sendSocks = sendSocks |
28 go recvTransport(recvSocks, recvWriter, status) |
33 go cl.recvTransport(recvSocks, recvWriter, status) |
29 go sendTransport(sendSocks, sendReader) |
34 go cl.sendTransport(sendSocks, sendReader) |
30 recvSocks <- sock |
35 recvSocks <- sock |
31 sendSocks <- sock |
36 sendSocks <- sock |
32 return &l1 |
37 return &l1 |
33 } |
38 } |
34 |
39 |
48 l1.sock = tls.Client(l1.sock, conf) |
53 l1.sock = tls.Client(l1.sock, conf) |
49 sendSockToSender(l1.sock) |
54 sendSockToSender(l1.sock) |
50 l1.recvSocks <- l1.sock |
55 l1.recvSocks <- l1.sock |
51 } |
56 } |
52 |
57 |
53 func recvTransport(socks <-chan net.Conn, w io.WriteCloser, |
58 func (cl *Client) recvTransport(socks <-chan net.Conn, w io.WriteCloser, |
54 status <-chan Status) { |
59 status <-chan Status) { |
55 |
60 |
56 defer w.Close() |
61 defer w.Close() |
57 var sock net.Conn |
62 var sock net.Conn |
58 p := make([]byte, 1024) |
63 p := make([]byte, 1024) |
59 for { |
64 for { |
60 select { |
65 select { |
61 case stat := <-status: |
66 case stat := <-status: |
62 if stat == StatusShutdown { |
67 if stat.Fatal() { |
63 return |
68 return |
64 } |
69 } |
65 |
70 |
66 case sock = <-socks: |
71 case sock = <-socks: |
67 default: |
72 default: |
76 if errno, ok := err.(*net.OpError); ok { |
81 if errno, ok := err.(*net.OpError); ok { |
77 if errno.Timeout() { |
82 if errno.Timeout() { |
78 continue |
83 continue |
79 } |
84 } |
80 } |
85 } |
81 Warn.Logf("recvTransport: %s", err) |
86 cl.setError(fmt.Errorf("recv: %v", err)) |
82 return |
87 return |
|
88 } |
|
89 if Debug { |
|
90 log.Printf("recv: %s", p[:nr]) |
83 } |
91 } |
84 nw, err := w.Write(p[:nr]) |
92 nw, err := w.Write(p[:nr]) |
85 if nw < nr { |
93 if nw < nr { |
86 Warn.Logf("recvTransport: %s", err) |
94 cl.setError(fmt.Errorf("recv: %v", err)) |
87 return |
95 return |
88 } |
96 } |
89 } |
97 } |
90 } |
98 } |
91 } |
99 } |
92 |
100 |
93 func sendTransport(socks <-chan net.Conn, r io.Reader) { |
101 func (cl *Client) sendTransport(socks <-chan net.Conn, r io.Reader) { |
94 var sock net.Conn |
102 var sock net.Conn |
95 p := make([]byte, 1024) |
103 p := make([]byte, 1024) |
96 for { |
104 for { |
97 nr, err := r.Read(p) |
105 nr, err := r.Read(p) |
98 if nr == 0 { |
106 if nr == 0 { |
99 Warn.Logf("sendTransport: %s", err) |
107 cl.setError(fmt.Errorf("send: %v", err)) |
100 break |
108 break |
|
109 } |
|
110 if nr > 0 && Debug { |
|
111 log.Printf("send: %s", p[:nr]) |
101 } |
112 } |
102 for nr > 0 { |
113 for nr > 0 { |
103 select { |
114 select { |
104 case sock = <-socks: |
115 case sock = <-socks: |
105 if sock != nil { |
116 if sock != nil { |