OLD | NEW |
1 /* | 1 /* |
2 * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks. | 2 * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks. |
3 * | 3 * |
4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 | 7 |
8 #include "cert.h" | 8 #include "cert.h" |
9 #include "ssl.h" | 9 #include "ssl.h" |
10 #include "sslimpl.h" | 10 #include "sslimpl.h" |
11 | 11 |
12 #if defined(WIN32) | 12 #if defined(WIN32) |
13 #define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); } | 13 #define MAP_ERROR(from, to) \ |
14 #define DEFINE_ERROR PRErrorCode err = PR_GetError(); | 14 if (err == from) { \ |
| 15 PORT_SetError(to); \ |
| 16 } |
| 17 #define DEFINE_ERROR PRErrorCode err = PR_GetError(); |
15 #else | 18 #else |
16 #define MAP_ERROR(from,to) | 19 #define MAP_ERROR(from, to) |
17 #define DEFINE_ERROR | 20 #define DEFINE_ERROR |
18 #endif | 21 #endif |
19 | 22 |
20 int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa) | 23 int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa) { |
21 { | 24 PRFileDesc *lower = ss->fd->lower; |
22 PRFileDesc *lower = ss->fd->lower; | 25 int rv; |
23 int rv; | |
24 | 26 |
25 rv = lower->methods->connect(lower, sa, ss->cTimeout); | 27 rv = lower->methods->connect(lower, sa, ss->cTimeout); |
26 return rv; | 28 return rv; |
27 } | 29 } |
28 | 30 |
29 int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr) | 31 int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr) { |
30 { | 32 PRFileDesc *lower = ss->fd->lower; |
31 PRFileDesc *lower = ss->fd->lower; | 33 int rv; |
32 int rv; | |
33 | 34 |
34 rv = lower->methods->bind(lower, addr); | 35 rv = lower->methods->bind(lower, addr); |
35 return rv; | 36 return rv; |
36 } | 37 } |
37 | 38 |
38 int ssl_DefListen(sslSocket *ss, int backlog) | 39 int ssl_DefListen(sslSocket *ss, int backlog) { |
39 { | 40 PRFileDesc *lower = ss->fd->lower; |
40 PRFileDesc *lower = ss->fd->lower; | 41 int rv; |
41 int rv; | |
42 | 42 |
43 rv = lower->methods->listen(lower, backlog); | 43 rv = lower->methods->listen(lower, backlog); |
44 return rv; | 44 return rv; |
45 } | 45 } |
46 | 46 |
47 int ssl_DefShutdown(sslSocket *ss, int how) | 47 int ssl_DefShutdown(sslSocket *ss, int how) { |
48 { | 48 PRFileDesc *lower = ss->fd->lower; |
49 PRFileDesc *lower = ss->fd->lower; | 49 int rv; |
50 int rv; | |
51 | 50 |
52 rv = lower->methods->shutdown(lower, how); | 51 rv = lower->methods->shutdown(lower, how); |
53 return rv; | 52 return rv; |
54 } | 53 } |
55 | 54 |
56 int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags) | 55 int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags) { |
57 { | 56 PRFileDesc *lower = ss->fd->lower; |
58 PRFileDesc *lower = ss->fd->lower; | 57 int rv; |
59 int rv; | |
60 | 58 |
61 rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout); | 59 rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout); |
62 if (rv < 0) { | 60 if (rv < 0) { |
63 » DEFINE_ERROR | 61 DEFINE_ERROR |
64 » MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) | 62 MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) |
65 } else if (rv > len) { | 63 } else if (rv > len) { |
66 » PORT_Assert(rv <= len); | 64 PORT_Assert(rv <= len); |
67 » PORT_SetError(PR_BUFFER_OVERFLOW_ERROR); | 65 PORT_SetError(PR_BUFFER_OVERFLOW_ERROR); |
68 » rv = SECFailure; | 66 rv = SECFailure; |
69 } | 67 } |
70 return rv; | 68 return rv; |
71 } | 69 } |
72 | 70 |
73 /* Default (unencrypted) send. | 71 /* Default (unencrypted) send. |
74 * For blocking sockets, always returns len or SECFailure, no short writes. | 72 * For blocking sockets, always returns len or SECFailure, no short writes. |
75 * For non-blocking sockets: | 73 * For non-blocking sockets: |
76 * Returns positive count if any data was written, else returns SECFailure. | 74 * Returns positive count if any data was written, else returns SECFailure. |
77 * Short writes may occur. Does not return SECWouldBlock. | 75 * Short writes may occur. Does not return SECWouldBlock. |
78 */ | 76 */ |
79 int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) | 77 int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) { |
80 { | 78 PRFileDesc *lower = ss->fd->lower; |
81 PRFileDesc *lower = ss->fd->lower; | 79 int sent = 0; |
82 int sent = 0; | |
83 | 80 |
84 #if NSS_DISABLE_NAGLE_DELAYS | 81 #if NSS_DISABLE_NAGLE_DELAYS |
85 /* Although this is overkill, we disable Nagle delays completely for· | 82 /* Although this is overkill, we disable Nagle delays completely for |
86 ** SSL sockets. | 83 ** SSL sockets. |
87 */ | 84 */ |
88 if (ss->opt.useSecurity && !ss->delayDisabled) { | 85 if (ss->opt.useSecurity && !ss->delayDisabled) { |
89 » ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */ | 86 ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */ |
90 » ss->delayDisabled = 1; | 87 ss->delayDisabled = 1; |
| 88 } |
| 89 #endif |
| 90 do { |
| 91 int rv = lower->methods->send(lower, (const void *)(buf + sent), len - sent, |
| 92 flags, ss->wTimeout); |
| 93 if (rv < 0) { |
| 94 PRErrorCode err = PR_GetError(); |
| 95 if (err == PR_WOULD_BLOCK_ERROR) { |
| 96 ss->lastWriteBlocked = 1; |
| 97 return sent ? sent : SECFailure; |
| 98 } |
| 99 ss->lastWriteBlocked = 0; |
| 100 MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) |
| 101 /* Loser */ |
| 102 return rv; |
91 } | 103 } |
92 #endif | 104 sent += rv; |
93 do { | 105 |
94 » int rv = lower->methods->send(lower, (const void *)(buf + sent),· | 106 if (IS_DTLS(ss) && (len > sent)) { |
95 » len - sent, flags, ss->wTimeout); | 107 /* We got a partial write so just return it */ |
96 » if (rv < 0) { | 108 return sent; |
97 » PRErrorCode err = PR_GetError(); | 109 } |
98 » if (err == PR_WOULD_BLOCK_ERROR) { | 110 } while (len > sent); |
99 » » ss->lastWriteBlocked = 1; | 111 ss->lastWriteBlocked = 0; |
100 » » return sent ? sent : SECFailure; | 112 return sent; |
101 » } | |
102 » ss->lastWriteBlocked = 0; | |
103 » MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) | |
104 » /* Loser */ | |
105 » return rv; | |
106 » } | |
107 » sent += rv; | |
108 »······· | |
109 » if (IS_DTLS(ss) && (len > sent)) {· | |
110 » /* We got a partial write so just return it */ | |
111 » return sent; | |
112 » } | |
113 } while (len > sent); | |
114 ss->lastWriteBlocked = 0; | |
115 return sent; | |
116 } | 113 } |
117 | 114 |
118 int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) | 115 int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) { |
119 { | 116 PRFileDesc *lower = ss->fd->lower; |
120 PRFileDesc *lower = ss->fd->lower; | 117 int rv; |
121 int rv; | |
122 | 118 |
123 rv = lower->methods->read(lower, (void *)buf, len); | 119 rv = lower->methods->read(lower, (void *)buf, len); |
124 if (rv < 0) { | 120 if (rv < 0) { |
125 » DEFINE_ERROR | 121 DEFINE_ERROR |
126 » MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) | 122 MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) |
127 } | 123 } |
128 return rv; | 124 return rv; |
129 } | 125 } |
130 | 126 |
131 int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len) | 127 int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len) { |
132 { | 128 PRFileDesc *lower = ss->fd->lower; |
133 PRFileDesc *lower = ss->fd->lower; | 129 int sent = 0; |
134 int sent = 0; | |
135 | 130 |
136 do { | 131 do { |
137 » int rv = lower->methods->write(lower, (const void *)(buf + sent), | 132 int rv = |
138 » len - sent); | 133 lower->methods->write(lower, (const void *)(buf + sent), len - sent); |
139 » if (rv < 0) { | 134 if (rv < 0) { |
140 » PRErrorCode err = PR_GetError(); | 135 PRErrorCode err = PR_GetError(); |
141 » if (err == PR_WOULD_BLOCK_ERROR) { | 136 if (err == PR_WOULD_BLOCK_ERROR) { |
142 » » ss->lastWriteBlocked = 1; | 137 ss->lastWriteBlocked = 1; |
143 » » return sent ? sent : SECFailure; | 138 return sent ? sent : SECFailure; |
144 » } | 139 } |
145 » ss->lastWriteBlocked = 0; | 140 ss->lastWriteBlocked = 0; |
146 » MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) | 141 MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) |
147 » /* Loser */ | 142 /* Loser */ |
148 » return rv; | 143 return rv; |
149 » } | 144 } |
150 » sent += rv; | 145 sent += rv; |
151 } while (len > sent); | 146 } while (len > sent); |
152 ss->lastWriteBlocked = 0; | 147 ss->lastWriteBlocked = 0; |
153 return sent; | 148 return sent; |
154 } | 149 } |
155 | 150 |
156 int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name) | 151 int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name) { |
157 { | 152 PRFileDesc *lower = ss->fd->lower; |
158 PRFileDesc *lower = ss->fd->lower; | 153 int rv; |
159 int rv; | |
160 | 154 |
161 rv = lower->methods->getpeername(lower, name); | 155 rv = lower->methods->getpeername(lower, name); |
162 return rv; | 156 return rv; |
163 } | 157 } |
164 | 158 |
165 int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name) | 159 int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name) { |
166 { | 160 PRFileDesc *lower = ss->fd->lower; |
167 PRFileDesc *lower = ss->fd->lower; | 161 int rv; |
168 int rv; | |
169 | 162 |
170 rv = lower->methods->getsockname(lower, name); | 163 rv = lower->methods->getsockname(lower, name); |
171 return rv; | 164 return rv; |
172 } | 165 } |
173 | 166 |
174 int ssl_DefClose(sslSocket *ss) | 167 int ssl_DefClose(sslSocket *ss) { |
175 { | 168 PRFileDesc *fd; |
176 PRFileDesc *fd; | 169 PRFileDesc *popped; |
177 PRFileDesc *popped; | 170 int rv; |
178 int rv; | |
179 | 171 |
180 fd = ss->fd; | 172 fd = ss->fd; |
181 | 173 |
182 /* First, remove the SSL layer PRFileDesc from the socket's stack, | 174 /* First, remove the SSL layer PRFileDesc from the socket's stack, |
183 ** then invoke the SSL layer's PRFileDesc destructor. | 175 ** then invoke the SSL layer's PRFileDesc destructor. |
184 ** This must happen before the next layer down is closed. | 176 ** This must happen before the next layer down is closed. |
185 */ | 177 */ |
186 PORT_Assert(fd->higher == NULL); | 178 PORT_Assert(fd->higher == NULL); |
187 if (fd->higher) { | 179 if (fd->higher) { |
188 » PORT_SetError(PR_BAD_DESCRIPTOR_ERROR); | 180 PORT_SetError(PR_BAD_DESCRIPTOR_ERROR); |
189 » return SECFailure; | 181 return SECFailure; |
190 } | 182 } |
191 ss->fd = NULL; | 183 ss->fd = NULL; |
192 | 184 |
193 /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on | 185 /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on |
194 ** the stack, and then remove the second one. This way, the address | 186 ** the stack, and then remove the second one. This way, the address |
195 ** of the PRFileDesc on the top of the stack doesn't change. | 187 ** of the PRFileDesc on the top of the stack doesn't change. |
196 */ | 188 */ |
197 popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); | 189 popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); |
198 popped->dtor(popped); | 190 popped->dtor(popped); |
199 | 191 |
200 /* fd is now the PRFileDesc for the next layer down. | 192 /* fd is now the PRFileDesc for the next layer down. |
201 ** Now close the underlying socket. | 193 ** Now close the underlying socket. |
202 */ | 194 */ |
203 rv = fd->methods->close(fd); | 195 rv = fd->methods->close(fd); |
204 | 196 |
205 ssl_FreeSocket(ss); | 197 ssl_FreeSocket(ss); |
206 | 198 |
207 SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d", | 199 SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d", SSL_GETPID(), fd, rv, |
208 » » SSL_GETPID(), fd, rv, PORT_GetError())); | 200 PORT_GetError())); |
209 return rv; | 201 return rv; |
210 } | 202 } |
OLD | NEW |