1 /* 2 * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks. 3 * 4 * ***** BEGIN LICENSE BLOCK ***** 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 6 * 7 * The contents of this file are subject to the Mozilla Public License Version 8 * 1.1 (the "License"); you may not use this file except in compliance with 9 * the License. You may obtain a copy of the License at 10 * http://www.mozilla.org/MPL/ 11 * 12 * Software distributed under the License is distributed on an "AS IS" basis, 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 14 * for the specific language governing rights and limitations under the 15 * License. 16 * 17 * The Original Code is the Netscape security libraries. 18 * 19 * The Initial Developer of the Original Code is 20 * Netscape Communications Corporation. 21 * Portions created by the Initial Developer are Copyright (C) 1994-2000 22 * the Initial Developer. All Rights Reserved. 23 * 24 * Contributor(s): 25 * 26 * Alternatively, the contents of this file may be used under the terms of 27 * either the GNU General Public License Version 2 or later (the "GPL"), or 28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 29 * in which case the provisions of the GPL or the LGPL are applicable instead 30 * of those above. If you wish to allow use of your version of this file only 31 * under the terms of either the GPL or the LGPL, and not to allow others to 32 * use your version of this file under the terms of the MPL, indicate your 33 * decision by deleting the provisions above and replace them with the notice 34 * and other provisions required by the GPL or the LGPL. If you do not delete 35 * the provisions above, a recipient may use your version of this file under 36 * the terms of any one of the MPL, the GPL or the LGPL. 37 * 38 * ***** END LICENSE BLOCK ***** */ 39 /* $Id: ssldef.c,v 1.11 2006/04/20 08:46:34 nelson%bolyard.com Exp $ */ 40 41 #include "cert.h" 42 #include "ssl.h" 43 #include "sslimpl.h" 44 45 #if defined(WIN32) 46 #define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); } 47 #define DEFINE_ERROR PRErrorCode err = PR_GetError(); 48 #else 49 #define MAP_ERROR(from,to) 50 #define DEFINE_ERROR 51 #endif 52 53 int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa) 54 { 55 PRFileDesc *lower = ss->fd->lower; 56 int rv; 57 58 rv = lower->methods->connect(lower, sa, ss->cTimeout); 59 return rv; 60 } 61 62 int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr) 63 { 64 PRFileDesc *lower = ss->fd->lower; 65 int rv; 66 67 rv = lower->methods->bind(lower, addr); 68 return rv; 69 } 70 71 int ssl_DefListen(sslSocket *ss, int backlog) 72 { 73 PRFileDesc *lower = ss->fd->lower; 74 int rv; 75 76 rv = lower->methods->listen(lower, backlog); 77 return rv; 78 } 79 80 int ssl_DefShutdown(sslSocket *ss, int how) 81 { 82 PRFileDesc *lower = ss->fd->lower; 83 int rv; 84 85 rv = lower->methods->shutdown(lower, how); 86 return rv; 87 } 88 89 int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags) 90 { 91 PRFileDesc *lower = ss->fd->lower; 92 int rv; 93 94 rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout); 95 if (rv < 0) { 96 DEFINE_ERROR 97 MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) 98 } else if (rv > len) { 99 PORT_Assert(rv <= len); 100 PORT_SetError(PR_BUFFER_OVERFLOW_ERROR); 101 rv = SECFailure; 102 } 103 return rv; 104 } 105 106 /* Default (unencrypted) send. 107 * For blocking sockets, always returns len or SECFailure, no short writes. 108 * For non-blocking sockets: 109 * Returns positive count if any data was written, else returns SECFailure. 110 * Short writes may occur. Does not return SECWouldBlock. 111 */ 112 int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) 113 { 114 PRFileDesc *lower = ss->fd->lower; 115 int sent = 0; 116 117 #if NSS_DISABLE_NAGLE_DELAYS 118 /* Although this is overkill, we disable Nagle delays completely for 119 ** SSL sockets. 120 */ 121 if (ss->opt.useSecurity && !ss->delayDisabled) { 122 ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */ 123 ss->delayDisabled = 1; 124 } 125 #endif 126 do { 127 int rv = lower->methods->send(lower, (const void *)(buf + sent), 128 len - sent, flags, ss->wTimeout); 129 if (rv < 0) { 130 PRErrorCode err = PR_GetError(); 131 if (err == PR_WOULD_BLOCK_ERROR) { 132 ss->lastWriteBlocked = 1; 133 return sent ? sent : SECFailure; 134 } 135 ss->lastWriteBlocked = 0; 136 MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) 137 /* Loser */ 138 return rv; 139 } 140 sent += rv; 141 } while (len > sent); 142 ss->lastWriteBlocked = 0; 143 return sent; 144 } 145 146 int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) 147 { 148 PRFileDesc *lower = ss->fd->lower; 149 int rv; 150 151 rv = lower->methods->read(lower, (void *)buf, len); 152 if (rv < 0) { 153 DEFINE_ERROR 154 MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR) 155 } 156 return rv; 157 } 158 159 int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len) 160 { 161 PRFileDesc *lower = ss->fd->lower; 162 int sent = 0; 163 164 do { 165 int rv = lower->methods->write(lower, (const void *)(buf + sent), 166 len - sent); 167 if (rv < 0) { 168 PRErrorCode err = PR_GetError(); 169 if (err == PR_WOULD_BLOCK_ERROR) { 170 ss->lastWriteBlocked = 1; 171 return sent ? sent : SECFailure; 172 } 173 ss->lastWriteBlocked = 0; 174 MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) 175 /* Loser */ 176 return rv; 177 } 178 sent += rv; 179 } while (len > sent); 180 ss->lastWriteBlocked = 0; 181 return sent; 182 } 183 184 int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name) 185 { 186 PRFileDesc *lower = ss->fd->lower; 187 int rv; 188 189 rv = lower->methods->getpeername(lower, name); 190 return rv; 191 } 192 193 int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name) 194 { 195 PRFileDesc *lower = ss->fd->lower; 196 int rv; 197 198 rv = lower->methods->getsockname(lower, name); 199 return rv; 200 } 201 202 int ssl_DefClose(sslSocket *ss) 203 { 204 PRFileDesc *fd; 205 PRFileDesc *popped; 206 int rv; 207 208 fd = ss->fd; 209 210 /* First, remove the SSL layer PRFileDesc from the socket's stack, 211 ** then invoke the SSL layer's PRFileDesc destructor. 212 ** This must happen before the next layer down is closed. 213 */ 214 PORT_Assert(fd->higher == NULL); 215 if (fd->higher) { 216 PORT_SetError(PR_BAD_DESCRIPTOR_ERROR); 217 return SECFailure; 218 } 219 ss->fd = NULL; 220 221 /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on 222 ** the stack, and then remove the second one. This way, the address 223 ** of the PRFileDesc on the top of the stack doesn't change. 224 */ 225 popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); 226 popped->dtor(popped); 227 228 /* fd is now the PRFileDesc for the next layer down. 229 ** Now close the underlying socket. 230 */ 231 rv = fd->methods->close(fd); 232 233 ssl_FreeSocket(ss); 234 235 SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d", 236 SSL_GETPID(), fd, rv, PORT_GetError())); 237 return rv; 238 } 239