1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ssl/ssldef.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,210 @@ 1.4 +/* 1.5 + * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks. 1.6 + * 1.7 + * This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#include "cert.h" 1.12 +#include "ssl.h" 1.13 +#include "sslimpl.h" 1.14 + 1.15 +#if defined(WIN32) 1.16 +#define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); } 1.17 +#define DEFINE_ERROR PRErrorCode err = PR_GetError(); 1.18 +#else 1.19 +#define MAP_ERROR(from,to) 1.20 +#define DEFINE_ERROR 1.21 +#endif 1.22 + 1.23 +int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa) 1.24 +{ 1.25 + PRFileDesc *lower = ss->fd->lower; 1.26 + int rv; 1.27 + 1.28 + rv = lower->methods->connect(lower, sa, ss->cTimeout); 1.29 + return rv; 1.30 +} 1.31 + 1.32 +int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr) 1.33 +{ 1.34 + PRFileDesc *lower = ss->fd->lower; 1.35 + int rv; 1.36 + 1.37 + rv = lower->methods->bind(lower, addr); 1.38 + return rv; 1.39 +} 1.40 + 1.41 +int ssl_DefListen(sslSocket *ss, int backlog) 1.42 +{ 1.43 + PRFileDesc *lower = ss->fd->lower; 1.44 + int rv; 1.45 + 1.46 + rv = lower->methods->listen(lower, backlog); 1.47 + return rv; 1.48 +} 1.49 + 1.50 +int ssl_DefShutdown(sslSocket *ss, int how) 1.51 +{ 1.52 + PRFileDesc *lower = ss->fd->lower; 1.53 + int rv; 1.54 + 1.55 + rv = lower->methods->shutdown(lower, how); 1.56 + return rv; 1.57 +} 1.58 + 1.59 +int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags) 1.60 +{ 1.61 + PRFileDesc *lower = ss->fd->lower; 1.62 + int rv; 1.63 + 1.64 + rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout); 1.65 + if (rv < 0) { 1.66 + DEFINE_ERROR 1.67 + MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) 1.68 + } else if (rv > len) { 1.69 + PORT_Assert(rv <= len); 1.70 + PORT_SetError(PR_BUFFER_OVERFLOW_ERROR); 1.71 + rv = SECFailure; 1.72 + } 1.73 + return rv; 1.74 +} 1.75 + 1.76 +/* Default (unencrypted) send. 1.77 + * For blocking sockets, always returns len or SECFailure, no short writes. 1.78 + * For non-blocking sockets: 1.79 + * Returns positive count if any data was written, else returns SECFailure. 1.80 + * Short writes may occur. Does not return SECWouldBlock. 1.81 + */ 1.82 +int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) 1.83 +{ 1.84 + PRFileDesc *lower = ss->fd->lower; 1.85 + int sent = 0; 1.86 + 1.87 +#if NSS_DISABLE_NAGLE_DELAYS 1.88 + /* Although this is overkill, we disable Nagle delays completely for 1.89 + ** SSL sockets. 1.90 + */ 1.91 + if (ss->opt.useSecurity && !ss->delayDisabled) { 1.92 + ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */ 1.93 + ss->delayDisabled = 1; 1.94 + } 1.95 +#endif 1.96 + do { 1.97 + int rv = lower->methods->send(lower, (const void *)(buf + sent), 1.98 + len - sent, flags, ss->wTimeout); 1.99 + if (rv < 0) { 1.100 + PRErrorCode err = PR_GetError(); 1.101 + if (err == PR_WOULD_BLOCK_ERROR) { 1.102 + ss->lastWriteBlocked = 1; 1.103 + return sent ? sent : SECFailure; 1.104 + } 1.105 + ss->lastWriteBlocked = 0; 1.106 + MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) 1.107 + /* Loser */ 1.108 + return rv; 1.109 + } 1.110 + sent += rv; 1.111 + 1.112 + if (IS_DTLS(ss) && (len > sent)) { 1.113 + /* We got a partial write so just return it */ 1.114 + return sent; 1.115 + } 1.116 + } while (len > sent); 1.117 + ss->lastWriteBlocked = 0; 1.118 + return sent; 1.119 +} 1.120 + 1.121 +int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) 1.122 +{ 1.123 + PRFileDesc *lower = ss->fd->lower; 1.124 + int rv; 1.125 + 1.126 + rv = lower->methods->read(lower, (void *)buf, len); 1.127 + if (rv < 0) { 1.128 + DEFINE_ERROR 1.129 + MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) 1.130 + } 1.131 + return rv; 1.132 +} 1.133 + 1.134 +int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len) 1.135 +{ 1.136 + PRFileDesc *lower = ss->fd->lower; 1.137 + int sent = 0; 1.138 + 1.139 + do { 1.140 + int rv = lower->methods->write(lower, (const void *)(buf + sent), 1.141 + len - sent); 1.142 + if (rv < 0) { 1.143 + PRErrorCode err = PR_GetError(); 1.144 + if (err == PR_WOULD_BLOCK_ERROR) { 1.145 + ss->lastWriteBlocked = 1; 1.146 + return sent ? sent : SECFailure; 1.147 + } 1.148 + ss->lastWriteBlocked = 0; 1.149 + MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) 1.150 + /* Loser */ 1.151 + return rv; 1.152 + } 1.153 + sent += rv; 1.154 + } while (len > sent); 1.155 + ss->lastWriteBlocked = 0; 1.156 + return sent; 1.157 +} 1.158 + 1.159 +int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name) 1.160 +{ 1.161 + PRFileDesc *lower = ss->fd->lower; 1.162 + int rv; 1.163 + 1.164 + rv = lower->methods->getpeername(lower, name); 1.165 + return rv; 1.166 +} 1.167 + 1.168 +int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name) 1.169 +{ 1.170 + PRFileDesc *lower = ss->fd->lower; 1.171 + int rv; 1.172 + 1.173 + rv = lower->methods->getsockname(lower, name); 1.174 + return rv; 1.175 +} 1.176 + 1.177 +int ssl_DefClose(sslSocket *ss) 1.178 +{ 1.179 + PRFileDesc *fd; 1.180 + PRFileDesc *popped; 1.181 + int rv; 1.182 + 1.183 + fd = ss->fd; 1.184 + 1.185 + /* First, remove the SSL layer PRFileDesc from the socket's stack, 1.186 + ** then invoke the SSL layer's PRFileDesc destructor. 1.187 + ** This must happen before the next layer down is closed. 1.188 + */ 1.189 + PORT_Assert(fd->higher == NULL); 1.190 + if (fd->higher) { 1.191 + PORT_SetError(PR_BAD_DESCRIPTOR_ERROR); 1.192 + return SECFailure; 1.193 + } 1.194 + ss->fd = NULL; 1.195 + 1.196 + /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on 1.197 + ** the stack, and then remove the second one. This way, the address 1.198 + ** of the PRFileDesc on the top of the stack doesn't change. 1.199 + */ 1.200 + popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); 1.201 + popped->dtor(popped); 1.202 + 1.203 + /* fd is now the PRFileDesc for the next layer down. 1.204 + ** Now close the underlying socket. 1.205 + */ 1.206 + rv = fd->methods->close(fd); 1.207 + 1.208 + ssl_FreeSocket(ss); 1.209 + 1.210 + SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d", 1.211 + SSL_GETPID(), fd, rv, PORT_GetError())); 1.212 + return rv; 1.213 +}