security/nss/lib/ssl/ssldef.c

changeset 0
6474c204b198
     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 +}

mercurial