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