Coverage Report

Created: 2025-06-24 06:49

/src/nss/lib/ssl/ssldef.c
Line
Count
Source (jump to first uncovered line)
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
0
{
26
0
    PRFileDesc *lower = ss->fd->lower;
27
0
    int rv;
28
29
0
    rv = lower->methods->connect(lower, sa, ss->cTimeout);
30
0
    return rv;
31
0
}
32
33
int
34
ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
35
0
{
36
0
    PRFileDesc *lower = ss->fd->lower;
37
0
    int rv;
38
39
0
    rv = lower->methods->bind(lower, addr);
40
0
    return rv;
41
0
}
42
43
int
44
ssl_DefListen(sslSocket *ss, int backlog)
45
0
{
46
0
    PRFileDesc *lower = ss->fd->lower;
47
0
    int rv;
48
49
0
    rv = lower->methods->listen(lower, backlog);
50
0
    return rv;
51
0
}
52
53
int
54
ssl_DefShutdown(sslSocket *ss, int how)
55
0
{
56
0
    PRFileDesc *lower = ss->fd->lower;
57
0
    int rv;
58
59
0
    rv = lower->methods->shutdown(lower, how);
60
0
    return rv;
61
0
}
62
63
int
64
ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
65
2.65M
{
66
2.65M
    PRFileDesc *lower = ss->fd->lower;
67
2.65M
    int rv;
68
69
2.65M
    PORT_Assert(buf && len > 0);
70
71
2.65M
    rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout);
72
2.65M
    if (rv < 0) {
73
0
        DEFINE_ERROR
74
0
        MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
75
2.65M
    } else if (rv > len) {
76
0
        PORT_Assert(rv <= len);
77
0
        PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
78
0
        rv = SECFailure;
79
0
    }
80
2.65M
    return rv;
81
2.65M
}
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
318k
{
92
318k
    PRFileDesc *lower = ss->fd->lower;
93
318k
    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
318k
    do {
105
318k
        int rv = lower->methods->send(lower, (const void *)(buf + sent),
106
318k
                                      len - sent, flags, ss->wTimeout);
107
318k
        if (rv < 0) {
108
0
            PRErrorCode err = PR_GetError();
109
0
            if (err == PR_WOULD_BLOCK_ERROR) {
110
0
                ss->lastWriteBlocked = 1;
111
0
                return sent ? sent : SECFailure;
112
0
            }
113
0
            ss->lastWriteBlocked = 0;
114
0
            MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
115
            /* Loser */
116
0
            return rv;
117
0
        }
118
318k
        sent += rv;
119
120
318k
        if (IS_DTLS(ss) && (len > sent)) {
121
            /* We got a partial write so just return it */
122
0
            return sent;
123
0
        }
124
318k
    } while (len > sent);
125
318k
    ss->lastWriteBlocked = 0;
126
318k
    return sent;
127
318k
}
128
129
int
130
ssl_DefRead(sslSocket *ss, unsigned char *buf, int len)
131
0
{
132
0
    PRFileDesc *lower = ss->fd->lower;
133
0
    int rv;
134
135
0
    rv = lower->methods->read(lower, (void *)buf, len);
136
0
    if (rv < 0) {
137
0
        DEFINE_ERROR
138
0
        MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
139
0
    }
140
0
    return rv;
141
0
}
142
143
int
144
ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len)
145
0
{
146
0
    PRFileDesc *lower = ss->fd->lower;
147
0
    int sent = 0;
148
149
0
    do {
150
0
        int rv = lower->methods->write(lower, (const void *)(buf + sent),
151
0
                                       len - sent);
152
0
        if (rv < 0) {
153
0
            PRErrorCode err = PR_GetError();
154
0
            if (err == PR_WOULD_BLOCK_ERROR) {
155
0
                ss->lastWriteBlocked = 1;
156
0
                return sent ? sent : SECFailure;
157
0
            }
158
0
            ss->lastWriteBlocked = 0;
159
0
            MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
160
            /* Loser */
161
0
            return rv;
162
0
        }
163
0
        sent += rv;
164
0
    } while (len > sent);
165
0
    ss->lastWriteBlocked = 0;
166
0
    return sent;
167
0
}
168
169
int
170
ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
171
68.7k
{
172
68.7k
    PRFileDesc *lower = ss->fd->lower;
173
68.7k
    int rv;
174
175
68.7k
    rv = lower->methods->getpeername(lower, name);
176
68.7k
    return rv;
177
68.7k
}
178
179
int
180
ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
181
0
{
182
0
    PRFileDesc *lower = ss->fd->lower;
183
0
    int rv;
184
185
0
    rv = lower->methods->getsockname(lower, name);
186
0
    return rv;
187
0
}
188
189
int
190
ssl_DefClose(sslSocket *ss)
191
68.7k
{
192
68.7k
    PRFileDesc *fd;
193
68.7k
    PRFileDesc *popped;
194
68.7k
    int rv;
195
196
68.7k
    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
68.7k
    PORT_Assert(fd->higher == NULL);
203
68.7k
    if (fd->higher) {
204
0
        PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
205
0
        return SECFailure;
206
0
    }
207
68.7k
    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
68.7k
    popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
214
68.7k
    popped->dtor(popped);
215
216
    /* fd is now the PRFileDesc for the next layer down.
217
    ** Now close the underlying socket.
218
    */
219
68.7k
    rv = fd->methods->close(fd);
220
221
68.7k
    ssl_FreeSocket(ss);
222
223
68.7k
    SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d",
224
68.7k
                SSL_GETPID(), fd, rv, PORT_GetError()));
225
68.7k
    return rv;
226
68.7k
}