Back to index

lightning-sunbird  0.9+nobinonly
ssldef.c
Go to the documentation of this file.
00001 /*
00002  * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks.
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is the Netscape security libraries.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 /* $Id: ssldef.c,v 1.10.2.1 2006/04/23 03:05:42 nelson%bolyard.com Exp $ */
00040 
00041 #include "cert.h"
00042 #include "ssl.h"
00043 #include "sslimpl.h"
00044 
00045 #if defined(WIN32)
00046 #define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); }
00047 #define DEFINE_ERROR       PRErrorCode err = PR_GetError();
00048 #else
00049 #define MAP_ERROR(from,to)
00050 #define DEFINE_ERROR
00051 #endif
00052 
00053 int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
00054 {
00055     PRFileDesc *lower = ss->fd->lower;
00056     int rv;
00057 
00058     rv = lower->methods->connect(lower, sa, ss->cTimeout);
00059     return rv;
00060 }
00061 
00062 int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
00063 {
00064     PRFileDesc *lower = ss->fd->lower;
00065     int rv;
00066 
00067     rv = lower->methods->bind(lower, addr);
00068     return rv;
00069 }
00070 
00071 int ssl_DefListen(sslSocket *ss, int backlog)
00072 {
00073     PRFileDesc *lower = ss->fd->lower;
00074     int rv;
00075 
00076     rv = lower->methods->listen(lower, backlog);
00077     return rv;
00078 }
00079 
00080 int ssl_DefShutdown(sslSocket *ss, int how)
00081 {
00082     PRFileDesc *lower = ss->fd->lower;
00083     int rv;
00084 
00085     rv = lower->methods->shutdown(lower, how);
00086     return rv;
00087 }
00088 
00089 int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
00090 {
00091     PRFileDesc *lower = ss->fd->lower;
00092     int rv;
00093 
00094     rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout);
00095     if (rv < 0) {
00096        DEFINE_ERROR
00097        MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
00098     } else if (rv > len) {
00099        PORT_Assert(rv <= len);
00100        PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
00101        rv = SECFailure;
00102     }
00103     return rv;
00104 }
00105 
00106 /* Default (unencrypted) send.
00107  * For blocking sockets, always returns len or SECFailure, no short writes.
00108  * For non-blocking sockets:
00109  *   Returns positive count if any data was written, else returns SECFailure. 
00110  *   Short writes may occur.  Does not return SECWouldBlock.
00111  */
00112 int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
00113 {
00114     PRFileDesc *lower = ss->fd->lower;
00115     int sent = 0;
00116 
00117 #if NSS_DISABLE_NAGLE_DELAYS
00118     /* Although this is overkill, we disable Nagle delays completely for 
00119     ** SSL sockets.
00120     */
00121     if (ss->opt.useSecurity && !ss->delayDisabled) {
00122        ssl_EnableNagleDelay(ss, PR_FALSE);   /* ignore error */
00123        ss->delayDisabled = 1;
00124     }
00125 #endif
00126     do {
00127        int rv = lower->methods->send(lower, (const void *)(buf + sent), 
00128                                      len - sent, flags, ss->wTimeout);
00129        if (rv < 0) {
00130            PRErrorCode err = PR_GetError();
00131            if (err == PR_WOULD_BLOCK_ERROR) {
00132               ss->lastWriteBlocked = 1;
00133               return sent ? sent : SECFailure;
00134            }
00135            ss->lastWriteBlocked = 0;
00136            MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
00137            /* Loser */
00138            return rv;
00139        }
00140        sent += rv;
00141     } while (len > sent);
00142     ss->lastWriteBlocked = 0;
00143     return sent;
00144 }
00145 
00146 int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len)
00147 {
00148     PRFileDesc *lower = ss->fd->lower;
00149     int rv;
00150 
00151     rv = lower->methods->read(lower, (void *)buf, len);
00152     if (rv < 0) {
00153        DEFINE_ERROR
00154        MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
00155     }
00156     return rv;
00157 }
00158 
00159 int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len)
00160 {
00161     PRFileDesc *lower = ss->fd->lower;
00162     int sent = 0;
00163 
00164     do {
00165        int rv = lower->methods->write(lower, (const void *)(buf + sent), 
00166                                       len - sent);
00167        if (rv < 0) {
00168            PRErrorCode err = PR_GetError();
00169            if (err == PR_WOULD_BLOCK_ERROR) {
00170               ss->lastWriteBlocked = 1;
00171               return sent ? sent : SECFailure;
00172            }
00173            ss->lastWriteBlocked = 0;
00174            MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
00175            /* Loser */
00176            return rv;
00177        }
00178        sent += rv;
00179     } while (len > sent);
00180     ss->lastWriteBlocked = 0;
00181     return sent;
00182 }
00183 
00184 int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
00185 {
00186     PRFileDesc *lower = ss->fd->lower;
00187     int rv;
00188 
00189     rv = lower->methods->getpeername(lower, name);
00190     return rv;
00191 }
00192 
00193 int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
00194 {
00195     PRFileDesc *lower = ss->fd->lower;
00196     int rv;
00197 
00198     rv = lower->methods->getsockname(lower, name);
00199     return rv;
00200 }
00201 
00202 int ssl_DefClose(sslSocket *ss)
00203 {
00204     PRFileDesc *fd;
00205     PRFileDesc *popped;
00206     int         rv;
00207 
00208     fd    = ss->fd;
00209 
00210     /* First, remove the SSL layer PRFileDesc from the socket's stack, 
00211     ** then invoke the SSL layer's PRFileDesc destructor.
00212     ** This must happen before the next layer down is closed.
00213     */
00214     PORT_Assert(fd->higher == NULL);
00215     if (fd->higher) {
00216        PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
00217        return SECFailure;
00218     }
00219     ss->fd = NULL;
00220 
00221     /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on
00222     ** the stack, and then remove the second one.  This way, the address
00223     ** of the PRFileDesc on the top of the stack doesn't change.
00224     */
00225     popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); 
00226     popped->dtor(popped);
00227 
00228     /* fd is now the PRFileDesc for the next layer down.
00229     ** Now close the underlying socket. 
00230     */
00231     rv = fd->methods->close(fd);
00232 
00233     ssl_FreeSocket(ss);
00234 
00235     SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d",
00236               SSL_GETPID(), fd, rv, PORT_GetError()));
00237     return rv;
00238 }