Coverage Report

Created: 2026-06-07 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mosquitto/lib/net_mosq.c
Line
Count
Source
1
/*
2
Copyright (c) 2009-2021 Roger Light <roger@atchoo.org>
3
4
All rights reserved. This program and the accompanying materials
5
are made available under the terms of the Eclipse Public License 2.0
6
and Eclipse Distribution License v1.0 which accompany this distribution.
7
8
The Eclipse Public License is available at
9
   https://www.eclipse.org/legal/epl-2.0/
10
and the Eclipse Distribution License is available at
11
  http://www.eclipse.org/org/documents/edl-v10.php.
12
13
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
14
15
Contributors:
16
   Roger Light - initial implementation and documentation.
17
*/
18
19
#define _GNU_SOURCE
20
#include "config.h"
21
22
#include <assert.h>
23
#include <errno.h>
24
#include <fcntl.h>
25
#include <stdio.h>
26
#include <string.h>
27
#ifndef WIN32
28
#define _GNU_SOURCE
29
#include <netdb.h>
30
#include <netinet/tcp.h>
31
#include <sys/socket.h>
32
#include <unistd.h>
33
#else
34
#include <winsock2.h>
35
#include <ws2tcpip.h>
36
#endif
37
38
#ifdef __ANDROID__
39
#include <linux/in.h>
40
#include <linux/in6.h>
41
#include <sys/endian.h>
42
#endif
43
44
#ifdef HAVE_NETINET_IN_H
45
#  include <netinet/in.h>
46
#endif
47
48
#ifdef WITH_UNIX_SOCKETS
49
#  include <sys/un.h>
50
#endif
51
52
#ifdef __QNX__
53
#include <net/netbyte.h>
54
#endif
55
56
#ifdef WITH_TLS
57
#include <openssl/conf.h>
58
#include <openssl/engine.h>
59
#include <openssl/err.h>
60
#include <openssl/ui.h>
61
#include <tls_mosq.h>
62
#endif
63
64
#ifdef WITH_BROKER
65
#  include "mosquitto_broker_internal.h"
66
#  if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_LWS
67
#    include <libwebsockets.h>
68
#  endif
69
#else
70
#  include "read_handle.h"
71
#endif
72
73
#include "logging_mosq.h"
74
#include "mosquitto/mqtt_protocol.h"
75
#include "net_mosq.h"
76
#include "packet_mosq.h"
77
#include "util_mosq.h"
78
79
#ifdef WITH_TLS
80
int tls_ex_index_mosq = -1;
81
UI_METHOD *_ui_method = NULL;
82
83
static bool is_tls_initialized = false;
84
85
86
/* Functions taken from OpenSSL s_server/s_client */
87
static int ui_open(UI *ui)
88
0
{
89
0
  return UI_method_get_opener(UI_OpenSSL())(ui);
90
0
}
91
92
93
static int ui_read(UI *ui, UI_STRING *uis)
94
0
{
95
0
  return UI_method_get_reader(UI_OpenSSL())(ui, uis);
96
0
}
97
98
99
static int ui_write(UI *ui, UI_STRING *uis)
100
0
{
101
0
  return UI_method_get_writer(UI_OpenSSL())(ui, uis);
102
0
}
103
104
105
static int ui_close(UI *ui)
106
0
{
107
0
  return UI_method_get_closer(UI_OpenSSL())(ui);
108
0
}
109
110
111
static void setup_ui_method(void)
112
0
{
113
0
  _ui_method = UI_create_method("OpenSSL application user interface");
114
0
  UI_method_set_opener(_ui_method, ui_open);
115
0
  UI_method_set_reader(_ui_method, ui_read);
116
0
  UI_method_set_writer(_ui_method, ui_write);
117
0
  UI_method_set_closer(_ui_method, ui_close);
118
0
}
119
120
121
static void cleanup_ui_method(void)
122
8.12k
{
123
8.12k
  if(_ui_method){
124
0
    UI_destroy_method(_ui_method);
125
0
    _ui_method = NULL;
126
0
  }
127
8.12k
}
128
129
130
UI_METHOD *net__get_ui_method(void)
131
0
{
132
0
  if(!_ui_method){
133
0
    setup_ui_method();
134
0
  }
135
0
  return _ui_method;
136
0
}
137
138
#endif
139
140
141
int net__init(void)
142
8.12k
{
143
#ifdef WIN32
144
  WSADATA wsaData;
145
  if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){
146
    return MOSQ_ERR_UNKNOWN;
147
  }
148
#endif
149
150
#ifdef WITH_SRV
151
  ares_library_init(ARES_LIB_INIT_ALL);
152
#endif
153
154
8.12k
  return MOSQ_ERR_SUCCESS;
155
8.12k
}
156
157
158
void net__cleanup(void)
159
8.12k
{
160
8.12k
#ifdef WITH_TLS
161
8.12k
  cleanup_ui_method();
162
8.12k
  if(is_tls_initialized){
163
8.12k
    is_tls_initialized = false;
164
8.12k
  }
165
8.12k
#endif
166
167
#ifdef WITH_SRV
168
  ares_library_cleanup();
169
#endif
170
171
#ifdef WIN32
172
  WSACleanup();
173
#endif
174
8.12k
}
175
176
#ifdef WITH_TLS
177
178
179
void net__init_tls(void)
180
8.12k
{
181
8.12k
  if(is_tls_initialized){
182
0
    return;
183
0
  }
184
185
8.12k
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
186
8.12k
  ENGINE_load_builtin_engines();
187
8.12k
#endif
188
8.12k
  if(tls_ex_index_mosq == -1){
189
1
    tls_ex_index_mosq = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
190
1
  }
191
192
8.12k
  is_tls_initialized = true;
193
8.12k
}
194
#endif
195
196
197
bool net__is_connected(struct mosquitto *mosq)
198
17.8k
{
199
#if defined(WITH_BROKER) && defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_LWS
200
  return mosq->sock != INVALID_SOCKET || mosq->wsi != NULL;
201
#else
202
17.8k
  return mosq->sock != INVALID_SOCKET;
203
17.8k
#endif
204
17.8k
}
205
206
207
/* Close a socket associated with a context and set it to -1.
208
 * Returns 1 on failure (context is NULL)
209
 * Returns 0 on success.
210
 */
211
int net__socket_close(struct mosquitto *mosq)
212
11.2k
{
213
11.2k
  int rc = 0;
214
11.2k
#ifdef WITH_BROKER
215
11.2k
  struct mosquitto *mosq_found;
216
11.2k
#endif
217
218
11.2k
  assert(mosq);
219
11.2k
#ifdef WITH_TLS
220
#if defined(WITH_BROKER) && defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_LWS
221
  if(!mosq->wsi)
222
#endif
223
11.2k
  {
224
11.2k
    if(mosq->ssl){
225
0
      if(!SSL_in_init(mosq->ssl)){
226
0
        SSL_shutdown(mosq->ssl);
227
0
      }
228
0
      SSL_free(mosq->ssl);
229
0
      mosq->ssl = NULL;
230
0
    }
231
11.2k
  }
232
11.2k
#endif
233
234
#if defined(WITH_BROKER) && defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_LWS
235
  if(mosq->wsi){
236
    if(mosq->state != mosq_cs_disconnecting){
237
      mosquitto__set_state(mosq, mosq_cs_disconnect_ws);
238
    }
239
    lws_callback_on_writable(mosq->wsi);
240
    if(mosq->listener){
241
      mosq->listener->client_count--;
242
    }
243
  }else
244
#endif
245
11.2k
  {
246
11.2k
    if(net__is_connected(mosq)){
247
0
#ifdef WITH_BROKER
248
0
      HASH_FIND(hh_sock, db.contexts_by_sock, &mosq->sock, sizeof(mosq->sock), mosq_found);
249
0
      if(mosq_found){
250
0
        HASH_DELETE(hh_sock, db.contexts_by_sock, mosq_found);
251
0
      }
252
0
      if(mosq->listener && mosq->state != mosq_cs_disused){
253
0
        mosq->listener->client_count--;
254
0
      }
255
0
#endif
256
0
      rc = COMPAT_CLOSE(mosq->sock);
257
0
      mosq->sock = INVALID_SOCKET;
258
0
    }
259
11.2k
  }
260
261
11.2k
  return rc;
262
11.2k
}
263
264
265
/* Shutdown a socket.
266
 * Returns 1 on failure (context is NULL)
267
 * Returns 0 on success.
268
 */
269
int net__socket_shutdown(struct mosquitto *mosq)
270
0
{
271
0
  int rc = 0;
272
273
0
  assert(mosq);
274
275
0
  if(net__is_connected(mosq)){
276
0
    rc = COMPAT_SHUTDOWN(mosq->sock);
277
0
  }
278
279
0
  return rc;
280
0
}
281
282
283
#ifdef FINAL_WITH_TLS_PSK
284
285
286
static unsigned int psk_client_callback(SSL *ssl, const char *hint,
287
    char *identity, unsigned int max_identity_len,
288
    unsigned char *psk, unsigned int max_psk_len)
289
0
{
290
0
  struct mosquitto *mosq;
291
0
  int len;
292
293
0
  UNUSED(hint);
294
295
0
  mosq = SSL_get_ex_data(ssl, tls_ex_index_mosq);
296
0
  if(!mosq){
297
0
    return 0;
298
0
  }
299
300
0
  snprintf(identity, max_identity_len, "%s", mosq->tls_psk_identity);
301
302
0
  len = mosquitto__hex2bin(mosq->tls_psk, psk, (int)max_psk_len);
303
0
  if(len < 0){
304
0
    return 0;
305
0
  }
306
0
  return (unsigned int)len;
307
0
}
308
#endif
309
310
#if defined(WITH_BROKER) && defined(__GLIBC__) && defined(WITH_ADNS)
311
312
313
/* Async connect, part 1 (dns lookup) */
314
int net__try_connect_step1(struct mosquitto *mosq, const char *host)
315
{
316
  int s;
317
  void *sevp = NULL;
318
  struct addrinfo *hints;
319
  struct addrinfo *ar_request;
320
321
  if(mosq->adns){
322
    gai_cancel(mosq->adns);
323
324
    ar_request = (struct addrinfo *)mosq->adns->ar_request;
325
    mosquitto_FREE(ar_request);
326
    mosquitto_FREE(mosq->adns);
327
  }
328
  mosq->adns = mosquitto_calloc(1, sizeof(struct gaicb));
329
  if(!mosq->adns){
330
    return MOSQ_ERR_NOMEM;
331
  }
332
333
  hints = mosquitto_calloc(1, sizeof(struct addrinfo));
334
  if(!hints){
335
    mosquitto_FREE(mosq->adns);
336
    return MOSQ_ERR_NOMEM;
337
  }
338
339
  hints->ai_family = AF_UNSPEC;
340
  hints->ai_socktype = SOCK_STREAM;
341
342
  mosq->adns->ar_name = host;
343
  mosq->adns->ar_request = hints;
344
345
  s = getaddrinfo_a(GAI_NOWAIT, &mosq->adns, 1, sevp);
346
  if(s){
347
    errno = s;
348
    if(mosq->adns){
349
      ar_request = (struct addrinfo *)mosq->adns->ar_request;
350
      mosquitto_FREE(ar_request);
351
      mosquitto_FREE(mosq->adns);
352
    }
353
    return MOSQ_ERR_EAI;
354
  }
355
356
  return MOSQ_ERR_SUCCESS;
357
}
358
359
360
/* Async connect part 2, the connection. */
361
int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *sock)
362
{
363
  struct addrinfo *ainfo, *rp;
364
  struct addrinfo *ar_request;
365
  int rc;
366
367
  ainfo = mosq->adns->ar_result;
368
369
  for(rp = ainfo; rp != NULL; rp = rp->ai_next){
370
    *sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
371
    if(*sock == INVALID_SOCKET){
372
      continue;
373
    }
374
375
    if(rp->ai_family == AF_INET){
376
      ((struct sockaddr_in *)rp->ai_addr)->sin_port = htons(port);
377
    }else if(rp->ai_family == AF_INET6){
378
      ((struct sockaddr_in6 *)rp->ai_addr)->sin6_port = htons(port);
379
    }else{
380
      COMPAT_CLOSE(*sock);
381
      *sock = INVALID_SOCKET;
382
      continue;
383
    }
384
385
    /* Set non-blocking */
386
    if(net__socket_nonblock(sock)){
387
      continue;
388
    }
389
390
    rc = connect(*sock, rp->ai_addr, rp->ai_addrlen);
391
    WINDOWS_SET_ERRNO();
392
    if(rc == 0 || errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK){
393
      if(rc < 0 && (errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK)){
394
        rc = MOSQ_ERR_CONN_PENDING;
395
      }
396
397
      /* Set non-blocking */
398
      if(net__socket_nonblock(sock)){
399
        continue;
400
      }
401
      break;
402
    }
403
404
    COMPAT_CLOSE(*sock);
405
    *sock = INVALID_SOCKET;
406
  }
407
  freeaddrinfo(mosq->adns->ar_result);
408
  mosq->adns->ar_result = NULL;
409
410
  ar_request = (struct addrinfo *)mosq->adns->ar_request;
411
  mosquitto_FREE(ar_request);
412
  mosquitto_FREE(mosq->adns);
413
414
  if(!rp){
415
    return MOSQ_ERR_ERRNO;
416
  }
417
418
  return rc;
419
}
420
421
#endif
422
423
424
static int net__try_connect_tcp(const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking)
425
0
{
426
0
  struct addrinfo hints;
427
0
  struct addrinfo *ainfo, *rp;
428
0
  struct addrinfo *ainfo_bind, *rp_bind;
429
0
  int s;
430
0
  int rc = MOSQ_ERR_SUCCESS;
431
432
0
  ainfo_bind = NULL;
433
434
0
  *sock = INVALID_SOCKET;
435
0
  memset(&hints, 0, sizeof(struct addrinfo));
436
0
  hints.ai_family = AF_UNSPEC;
437
0
  hints.ai_socktype = SOCK_STREAM;
438
439
0
  s = getaddrinfo(host, NULL, &hints, &ainfo);
440
0
  if(s){
441
0
    errno = s;
442
0
    return MOSQ_ERR_EAI;
443
0
  }
444
445
0
  if(bind_address){
446
0
    s = getaddrinfo(bind_address, NULL, &hints, &ainfo_bind);
447
0
    if(s){
448
0
      freeaddrinfo(ainfo);
449
0
      errno = s;
450
0
      return MOSQ_ERR_EAI;
451
0
    }
452
0
  }
453
454
0
  for(rp = ainfo; rp != NULL; rp = rp->ai_next){
455
0
    *sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
456
0
    if(*sock == INVALID_SOCKET){
457
0
      continue;
458
0
    }
459
460
0
    if(rp->ai_family == AF_INET){
461
0
      ((struct sockaddr_in *)rp->ai_addr)->sin_port = htons(port);
462
0
    }else if(rp->ai_family == AF_INET6){
463
0
      ((struct sockaddr_in6 *)rp->ai_addr)->sin6_port = htons(port);
464
0
    }else{
465
0
      COMPAT_CLOSE(*sock);
466
0
      *sock = INVALID_SOCKET;
467
0
      continue;
468
0
    }
469
470
0
    if(bind_address){
471
0
      for(rp_bind = ainfo_bind; rp_bind != NULL; rp_bind = rp_bind->ai_next){
472
0
        if(bind(*sock, rp_bind->ai_addr, rp_bind->ai_addrlen) == 0){
473
0
          break;
474
0
        }
475
0
      }
476
0
      if(!rp_bind){
477
0
        COMPAT_CLOSE(*sock);
478
0
        *sock = INVALID_SOCKET;
479
0
        continue;
480
0
      }
481
0
    }
482
483
0
    if(!blocking){
484
      /* Set non-blocking */
485
0
      if(net__socket_nonblock(sock)){
486
0
        continue;
487
0
      }
488
0
    }
489
490
0
    rc = connect(*sock, rp->ai_addr, rp->ai_addrlen);
491
0
    WINDOWS_SET_ERRNO();
492
0
    if(rc == 0 || errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK){
493
0
      if(rc < 0 && (errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK)){
494
0
        rc = MOSQ_ERR_CONN_PENDING;
495
0
      }
496
497
0
      if(blocking){
498
        /* Set non-blocking */
499
0
        if(net__socket_nonblock(sock)){
500
0
          continue;
501
0
        }
502
0
      }
503
0
      break;
504
0
    }
505
506
0
    COMPAT_CLOSE(*sock);
507
0
    *sock = INVALID_SOCKET;
508
0
  }
509
0
  freeaddrinfo(ainfo);
510
0
  if(bind_address){
511
0
    freeaddrinfo(ainfo_bind);
512
0
  }
513
0
  if(!rp){
514
0
    return MOSQ_ERR_ERRNO;
515
0
  }
516
0
  return rc;
517
0
}
518
519
520
#ifdef WITH_UNIX_SOCKETS
521
522
523
static int net__try_connect_unix(const char *host, mosq_sock_t *sock)
524
0
{
525
0
  struct sockaddr_un addr;
526
0
  int s;
527
0
  int rc;
528
529
0
  if(host == NULL || strlen(host) == 0 || strlen(host) > sizeof(addr.sun_path)-1){
530
0
    return MOSQ_ERR_INVAL;
531
0
  }
532
533
0
  memset(&addr, 0, sizeof(struct sockaddr_un));
534
0
  addr.sun_family = AF_UNIX;
535
0
  strncpy(addr.sun_path, host, sizeof(addr.sun_path)-1);
536
537
0
  s = socket(AF_UNIX, SOCK_STREAM, 0);
538
0
  if(s < 0){
539
0
    return MOSQ_ERR_ERRNO;
540
0
  }
541
0
  rc = net__socket_nonblock(&s);
542
0
  if(rc){
543
0
    return rc;
544
0
  }
545
546
0
  rc = connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un));
547
0
  if(rc < 0){
548
0
    close(s);
549
0
    return MOSQ_ERR_ERRNO;
550
0
  }
551
552
0
  *sock = s;
553
554
0
  return 0;
555
0
}
556
#endif
557
558
559
int net__try_connect(const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking)
560
0
{
561
0
  if(port == 0){
562
0
#ifdef WITH_UNIX_SOCKETS
563
0
    return net__try_connect_unix(host, sock);
564
#else
565
    return MOSQ_ERR_NOT_SUPPORTED;
566
#endif
567
0
  }else{
568
0
    return net__try_connect_tcp(host, port, sock, bind_address, blocking);
569
0
  }
570
0
}
571
572
573
#ifdef WITH_TLS
574
575
576
void net__print_ssl_error(struct mosquitto *mosq, const char *msg)
577
0
{
578
0
  char ebuf[256];
579
0
  unsigned long e;
580
0
  int num = 0;
581
0
  const char *msg_disp = msg == NULL ? "" : msg;
582
0
  e = ERR_get_error();
583
0
  while(e){
584
0
    log__printf(mosq, MOSQ_LOG_ERR, "OpenSSL Error %s[%d]: %s", msg_disp, num, ERR_error_string(e, ebuf));
585
0
    e = ERR_get_error();
586
0
    num++;
587
0
  }
588
0
}
589
590
591
int net__socket_connect_tls(struct mosquitto *mosq)
592
0
{
593
0
  long res;
594
595
0
  ERR_clear_error();
596
0
  if(mosq->tls_ocsp_required){
597
    /* Note: OCSP is available in all currently supported OpenSSL versions. */
598
0
    if((res=SSL_set_tlsext_status_type(mosq->ssl, TLSEXT_STATUSTYPE_ocsp)) != 1){
599
0
      log__printf(mosq, MOSQ_LOG_ERR, "Could not activate OCSP (error: %ld)", res);
600
0
      return MOSQ_ERR_OCSP;
601
0
    }
602
0
    if((res=SSL_CTX_set_tlsext_status_cb(mosq->ssl_ctx, mosquitto__verify_ocsp_status_cb)) != 1){
603
0
      log__printf(mosq, MOSQ_LOG_ERR, "Could not activate OCSP (error: %ld)", res);
604
0
      return MOSQ_ERR_OCSP;
605
0
    }
606
0
    if((res=SSL_CTX_set_tlsext_status_arg(mosq->ssl_ctx, mosq)) != 1){
607
0
      log__printf(mosq, MOSQ_LOG_ERR, "Could not activate OCSP (error: %ld)", res);
608
0
      return MOSQ_ERR_OCSP;
609
0
    }
610
0
  }
611
0
  SSL_set_connect_state(mosq->ssl);
612
0
  return MOSQ_ERR_SUCCESS;
613
0
}
614
#endif
615
616
617
#ifdef WITH_TLS
618
619
620
static int net__tls_load_ca(struct mosquitto *mosq)
621
0
{
622
0
  int ret;
623
624
0
  if(mosq->tls_use_os_certs){
625
0
    SSL_CTX_set_default_verify_paths(mosq->ssl_ctx);
626
0
  }
627
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
628
0
  if(mosq->tls_cafile || mosq->tls_capath){
629
0
    ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath);
630
0
    if(ret == 0){
631
0
#  ifdef WITH_BROKER
632
0
      if(mosq->tls_cafile && mosq->tls_capath){
633
0
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath);
634
0
      }else if(mosq->tls_cafile){
635
0
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile);
636
0
      }else{
637
0
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath);
638
0
      }
639
#  else
640
      if(mosq->tls_cafile && mosq->tls_capath){
641
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath);
642
      }else if(mosq->tls_cafile){
643
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile);
644
      }else{
645
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath);
646
      }
647
#  endif
648
0
      return MOSQ_ERR_TLS;
649
0
    }
650
0
  }
651
#else
652
  if(mosq->tls_cafile){
653
    ret = SSL_CTX_load_verify_file(mosq->ssl_ctx, mosq->tls_cafile);
654
    if(ret == 0){
655
#  ifdef WITH_BROKER
656
      log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile);
657
#  else
658
      log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile);
659
#  endif
660
      return MOSQ_ERR_TLS;
661
    }
662
  }
663
  if(mosq->tls_capath){
664
    ret = SSL_CTX_load_verify_dir(mosq->ssl_ctx, mosq->tls_capath);
665
    if(ret == 0){
666
#  ifdef WITH_BROKER
667
      log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath);
668
#  else
669
      log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath);
670
#  endif
671
      return MOSQ_ERR_TLS;
672
    }
673
  }
674
#endif
675
0
  return MOSQ_ERR_SUCCESS;
676
0
}
677
678
679
static int net__init_ssl_ctx(struct mosquitto *mosq)
680
0
{
681
0
  int ret;
682
0
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
683
0
  ENGINE *engine = NULL;
684
0
  EVP_PKEY *pkey;
685
0
#endif
686
0
  uint8_t tls_alpn_wire[256];
687
0
  uint8_t tls_alpn_len;
688
689
0
  net__init_tls();
690
691
0
  net__init_tls();
692
693
#ifndef WITH_BROKER
694
  if(mosq->user_ssl_ctx){
695
    mosq->ssl_ctx = mosq->user_ssl_ctx;
696
    if(!mosq->ssl_ctx_defaults){
697
      return MOSQ_ERR_SUCCESS;
698
    }else if(!mosq->tls_cafile && !mosq->tls_capath && !mosq->tls_psk){
699
      log__printf(mosq, MOSQ_LOG_ERR, "Error: If you use MOSQ_OPT_SSL_CTX then MOSQ_OPT_SSL_CTX_WITH_DEFAULTS must be true, or at least one of cafile, capath or psk must be specified.");
700
      return MOSQ_ERR_INVAL;
701
    }
702
  }
703
#endif
704
705
  /* Apply default SSL_CTX settings. This is only used if MOSQ_OPT_SSL_CTX
706
   * has not been set, or if both of MOSQ_OPT_SSL_CTX and
707
   * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS are set. */
708
0
  if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk || mosq->tls_use_os_certs){
709
0
    if(!mosq->ssl_ctx){
710
711
0
      mosq->ssl_ctx = SSL_CTX_new(TLS_client_method());
712
713
0
      if(!mosq->ssl_ctx){
714
0
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context.");
715
0
        net__print_ssl_error(mosq, "while trying to create a SSL ctx");
716
0
        return MOSQ_ERR_TLS;
717
0
      }
718
0
    }
719
720
0
#ifdef SSL_OP_NO_TLSv1_3
721
0
    if(mosq->tls_psk){
722
0
      SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_TLSv1_3);
723
0
    }
724
0
#endif
725
726
0
    if(!mosq->tls_version){
727
0
      SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
728
0
#ifdef SSL_OP_NO_TLSv1_3
729
0
    }else if(!strcmp(mosq->tls_version, "tlsv1.3")){
730
0
      SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
731
0
#endif
732
0
    }else if(!strcmp(mosq->tls_version, "tlsv1.2")){
733
0
      SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
734
0
    }else{
735
0
      log__printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version);
736
0
      return MOSQ_ERR_INVAL;
737
0
    }
738
739
    /* Allow use of DHE ciphers */
740
0
    SSL_CTX_set_dh_auto(mosq->ssl_ctx, 1);
741
742
    /* Disable compression */
743
0
    SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_COMPRESSION);
744
745
    /* Set ALPN */
746
0
    if(mosq->tls_alpn){
747
0
      tls_alpn_len = (uint8_t)strnlen(mosq->tls_alpn, 254);
748
0
      tls_alpn_wire[0] = tls_alpn_len;  /* first byte is length of string */
749
0
      memcpy(tls_alpn_wire + 1, mosq->tls_alpn, tls_alpn_len);
750
0
      SSL_CTX_set_alpn_protos(mosq->ssl_ctx, tls_alpn_wire, tls_alpn_len + 1U);
751
0
    }
752
753
0
#ifdef SSL_MODE_RELEASE_BUFFERS
754
    /* Use even less memory per SSL connection. */
755
0
    SSL_CTX_set_mode(mosq->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
756
0
#endif
757
758
0
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
759
0
    if(mosq->tls_engine){
760
0
      engine = ENGINE_by_id(mosq->tls_engine);
761
0
      if(!engine){
762
0
        log__printf(mosq, MOSQ_LOG_ERR, "Error loading %s engine\n", mosq->tls_engine);
763
0
        return MOSQ_ERR_TLS;
764
0
      }
765
0
      if(!ENGINE_init(engine)){
766
0
        log__printf(mosq, MOSQ_LOG_ERR, "Failed engine initialisation\n");
767
0
        ENGINE_free(engine);
768
0
        return MOSQ_ERR_TLS;
769
0
      }
770
0
      ENGINE_set_default(engine, ENGINE_METHOD_ALL);
771
0
      ENGINE_free(engine); /* release the structural reference from ENGINE_by_id() */
772
0
    }
773
0
#endif
774
775
0
    if(mosq->tls_ciphers){
776
0
      ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers);
777
0
      if(ret == 0){
778
0
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers);
779
0
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
780
0
        ENGINE_FINISH(engine);
781
0
#endif
782
0
        net__print_ssl_error(mosq, "while trying to set the cipher list");
783
0
        return MOSQ_ERR_TLS;
784
0
      }
785
0
    }
786
787
0
    if(mosq->tls_13_ciphers){
788
0
      ret = SSL_CTX_set_ciphersuites(mosq->ssl_ctx, mosq->tls_13_ciphers);
789
0
      if(ret == 0){
790
0
        log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS 1.3 ciphersuites. Check cipher_tls13 list \"%s\".", mosq->tls_13_ciphers);
791
0
        return MOSQ_ERR_TLS;
792
0
      }
793
0
    }
794
795
0
    if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_use_os_certs){
796
0
      ret = net__tls_load_ca(mosq);
797
0
      if(ret != MOSQ_ERR_SUCCESS){
798
0
#  if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
799
0
        ENGINE_FINISH(engine);
800
0
#  endif
801
0
        net__print_ssl_error(mosq, "while trying to load the ca");
802
0
        return MOSQ_ERR_TLS;
803
0
      }
804
0
      if(mosq->tls_cert_reqs == 0){
805
0
        SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_NONE, NULL);
806
0
      }else{
807
0
        SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_PEER, mosquitto__server_certificate_verify);
808
0
      }
809
810
0
      if(mosq->tls_pw_callback){
811
0
        SSL_CTX_set_default_passwd_cb(mosq->ssl_ctx, mosq->tls_pw_callback);
812
0
        SSL_CTX_set_default_passwd_cb_userdata(mosq->ssl_ctx, mosq);
813
0
      }
814
815
0
      if(mosq->tls_certfile){
816
0
        ret = SSL_CTX_use_certificate_chain_file(mosq->ssl_ctx, mosq->tls_certfile);
817
0
        if(ret != 1){
818
0
#ifdef WITH_BROKER
819
0
          log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate, check bridge_certfile \"%s\".", mosq->tls_certfile);
820
#else
821
          log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile);
822
#endif
823
0
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
824
0
          ENGINE_FINISH(engine);
825
0
#endif
826
0
          net__print_ssl_error(mosq, "while trying to use the certificate chain file");
827
0
          return MOSQ_ERR_TLS;
828
0
        }
829
0
      }
830
0
      if(mosq->tls_keyfile){
831
0
        if(mosq->tls_keyform == mosq_k_engine){
832
0
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
833
0
          UI_METHOD *ui_method = net__get_ui_method();
834
0
          if(mosq->tls_engine_kpass_sha1){
835
0
            if(!ENGINE_ctrl_cmd(engine, ENGINE_SECRET_MODE, ENGINE_SECRET_MODE_SHA, NULL, NULL, 0)){
836
0
              log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set engine secret mode sha1");
837
0
              ENGINE_FINISH(engine);
838
0
              net__print_ssl_error(mosq, "while trying to set the engine ctrl cmd SECRET_MODE");
839
0
              return MOSQ_ERR_TLS;
840
0
            }
841
0
            if(!ENGINE_ctrl_cmd(engine, ENGINE_PIN, 0, mosq->tls_engine_kpass_sha1, NULL, 0)){
842
0
              log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set engine pin");
843
0
              ENGINE_FINISH(engine);
844
0
              net__print_ssl_error(mosq, "while trying to set the engine ctrl cmd PIN");
845
0
              return MOSQ_ERR_TLS;
846
0
            }
847
0
            ui_method = NULL;
848
0
          }
849
0
          pkey = ENGINE_load_private_key(engine, mosq->tls_keyfile, ui_method, NULL);
850
0
          if(!pkey){
851
0
            log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load engine private key file \"%s\".", mosq->tls_keyfile);
852
0
            ENGINE_FINISH(engine);
853
0
            net__print_ssl_error(mosq, "while trying to load the private key");
854
0
            return MOSQ_ERR_TLS;
855
0
          }
856
0
          if(SSL_CTX_use_PrivateKey(mosq->ssl_ctx, pkey) <= 0){
857
0
            log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to use engine private key file \"%s\".", mosq->tls_keyfile);
858
0
            ENGINE_FINISH(engine);
859
0
            net__print_ssl_error(mosq, "while trying to use the private key");
860
0
            return MOSQ_ERR_TLS;
861
0
          }
862
0
#endif
863
0
        }else{
864
0
          ret = SSL_CTX_use_PrivateKey_file(mosq->ssl_ctx, mosq->tls_keyfile, SSL_FILETYPE_PEM);
865
0
          if(ret != 1){
866
0
#ifdef WITH_BROKER
867
0
            log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file, check bridge_keyfile \"%s\".", mosq->tls_keyfile);
868
#else
869
            log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile);
870
#endif
871
0
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
872
0
            ENGINE_FINISH(engine);
873
0
#endif
874
0
            net__print_ssl_error(mosq, "while trying to use the private key file");
875
0
            return MOSQ_ERR_TLS;
876
0
          }
877
0
        }
878
0
        ret = SSL_CTX_check_private_key(mosq->ssl_ctx);
879
0
        if(ret != 1){
880
0
          log__printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent.");
881
0
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
882
0
          ENGINE_FINISH(engine);
883
0
#endif
884
0
          net__print_ssl_error(mosq, "while trying to check the private key");
885
0
          return MOSQ_ERR_TLS;
886
0
        }
887
0
      }
888
0
#ifdef FINAL_WITH_TLS_PSK
889
0
    }else if(mosq->tls_psk){
890
0
      SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback);
891
0
      if(mosq->tls_ciphers == NULL){
892
0
        SSL_CTX_set_cipher_list(mosq->ssl_ctx, "PSK");
893
0
      }
894
0
#endif
895
0
    }
896
0
  }
897
898
0
  return MOSQ_ERR_SUCCESS;
899
0
}
900
#endif
901
902
903
int net__socket_connect_step3(struct mosquitto *mosq, const char *host)
904
0
{
905
0
#ifdef WITH_TLS
906
0
  BIO *bio;
907
908
0
  int rc = net__init_ssl_ctx(mosq);
909
0
  if(rc){
910
0
    net__socket_close(mosq);
911
0
    return rc;
912
0
  }
913
914
0
  if(mosq->ssl_ctx){
915
0
    if(mosq->ssl){
916
0
      SSL_free(mosq->ssl);
917
0
    }
918
0
    mosq->ssl = SSL_new(mosq->ssl_ctx);
919
0
    if(!mosq->ssl){
920
0
      net__socket_close(mosq);
921
0
      net__print_ssl_error(mosq, "while creating a SSL object");
922
0
      return MOSQ_ERR_TLS;
923
0
    }
924
925
0
    if(!SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq)){
926
0
      net__socket_close(mosq);
927
0
      net__print_ssl_error(mosq, "while setting SSL ex data");
928
0
      return MOSQ_ERR_TLS;
929
0
    }
930
0
    bio = BIO_new_socket(mosq->sock, BIO_NOCLOSE);
931
0
    if(!bio){
932
0
      net__socket_close(mosq);
933
0
      net__print_ssl_error(mosq, "while trying to create a new socket");
934
0
      return MOSQ_ERR_TLS;
935
0
    }
936
0
    SSL_set_bio(mosq->ssl, bio, bio);
937
938
    /*
939
     * required for the SNI resolving
940
     */
941
0
    if(SSL_set_tlsext_host_name(mosq->ssl, host) != 1){
942
0
      net__socket_close(mosq);
943
0
      return MOSQ_ERR_TLS;
944
0
    }
945
0
    if(tls__set_verify_hostname(mosq, host)){
946
0
      return MOSQ_ERR_TLS;
947
0
    }
948
949
0
    if(net__socket_connect_tls(mosq)){
950
0
      net__socket_close(mosq);
951
0
      return MOSQ_ERR_TLS;
952
0
    }
953
954
0
  }
955
#else
956
  UNUSED(mosq);
957
  UNUSED(host);
958
#endif
959
0
  return MOSQ_ERR_SUCCESS;
960
0
}
961
962
963
/* Create a socket and connect it to 'ip' on port 'port'.  */
964
int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking)
965
0
{
966
0
  int rc, rc2;
967
968
0
  if(!mosq || !host){
969
0
    return MOSQ_ERR_INVAL;
970
0
  }
971
972
0
  rc = net__try_connect(host, port, &mosq->sock, bind_address, blocking);
973
0
  if(rc > 0){
974
0
    return rc;
975
0
  }
976
977
0
  if(mosq->tcp_nodelay && port){
978
0
    int flag = 1;
979
0
    if(setsockopt(mosq->sock, IPPROTO_TCP, TCP_NODELAY, (const void *)&flag, sizeof(int)) != 0){
980
0
      log__printf(mosq, MOSQ_LOG_WARNING, "Warning: Unable to set TCP_NODELAY.");
981
0
    }
982
0
  }
983
984
#if defined(WITH_SOCKS) && !defined(WITH_BROKER)
985
  if(!mosq->socks5_host)
986
#endif
987
0
  {
988
0
    rc2 = net__socket_connect_step3(mosq, host);
989
0
    if(rc2){
990
0
      return rc2;
991
0
    }
992
0
  }
993
994
0
  return rc;
995
0
}
996
997
998
#ifdef WITH_TLS
999
1000
1001
static void net__handle_ssl(struct mosquitto *mosq, int ret)
1002
0
{
1003
0
  int err;
1004
1005
0
  err = SSL_get_error(mosq->ssl, ret);
1006
0
  if(err == SSL_ERROR_WANT_READ){
1007
0
    errno = EAGAIN;
1008
0
  }else if(err == SSL_ERROR_WANT_WRITE){
1009
0
#ifdef WITH_BROKER
1010
0
    mux__add_out(mosq);
1011
#else
1012
    mosq->want_write = true;
1013
#endif
1014
0
    errno = EAGAIN;
1015
0
  }else if(err == SSL_ERROR_SSL){
1016
0
    net__print_ssl_error(mosq, "while trying to get the error");
1017
0
    errno = EPROTO;
1018
    /* else if SSL_ERROR_SYSCALL leave errno alone */
1019
0
  }
1020
0
  ERR_clear_error();
1021
#ifdef WIN32
1022
  WSASetLastError(errno);
1023
#endif
1024
0
}
1025
#endif
1026
1027
1028
ssize_t net__read(struct mosquitto *mosq, void *buf, size_t count)
1029
{
1030
#ifdef WITH_TLS
1031
  int ret;
1032
#endif
1033
  assert(mosq);
1034
  errno = 0;
1035
#ifdef WITH_TLS
1036
  if(mosq->ssl){
1037
    ERR_clear_error();
1038
    ret = SSL_read(mosq->ssl, buf, (int)count);
1039
    if(ret <= 0){
1040
      net__handle_ssl(mosq, ret);
1041
    }
1042
    return (ssize_t )ret;
1043
  }else
1044
#endif
1045
  {
1046
    /* Call normal read/recv */
1047
1048
#ifndef WIN32
1049
    return read(mosq->sock, buf, count);
1050
#else
1051
    return recv(mosq->sock, buf, count, 0);
1052
#endif
1053
  }
1054
}
1055
1056
1057
ssize_t net__write(struct mosquitto *mosq, const void *buf, size_t count)
1058
0
{
1059
0
#ifdef WITH_TLS
1060
0
  int ret;
1061
0
#endif
1062
0
  assert(mosq);
1063
1064
0
  errno = 0;
1065
0
#ifdef WITH_TLS
1066
0
  if(mosq->ssl){
1067
0
    ERR_clear_error();
1068
0
    mosq->want_write = false;
1069
0
    ret = SSL_write(mosq->ssl, buf, (int)count);
1070
0
    if(ret < 0){
1071
0
      net__handle_ssl(mosq, ret);
1072
0
    }
1073
0
    return (ssize_t )ret;
1074
0
  }else
1075
  /* Call normal write/send */
1076
0
#endif
1077
0
  {
1078
0
    return send(mosq->sock, buf, count, MSG_NOSIGNAL);
1079
0
  }
1080
0
}
1081
1082
1083
int net__socket_nonblock(mosq_sock_t *sock)
1084
0
{
1085
0
#ifndef WIN32
1086
0
  int opt;
1087
  /* Set non-blocking */
1088
0
  opt = fcntl(*sock, F_GETFL, 0);
1089
0
  if(opt == -1){
1090
0
    COMPAT_CLOSE(*sock);
1091
0
    *sock = INVALID_SOCKET;
1092
0
    return MOSQ_ERR_ERRNO;
1093
0
  }
1094
0
  if(fcntl(*sock, F_SETFL, opt | O_NONBLOCK) == -1){
1095
    /* If either fcntl fails, don't want to allow this client to connect. */
1096
0
    COMPAT_CLOSE(*sock);
1097
0
    *sock = INVALID_SOCKET;
1098
0
    return MOSQ_ERR_ERRNO;
1099
0
  }
1100
#else
1101
  unsigned long opt = 1;
1102
  if(ioctlsocket(*sock, FIONBIO, &opt)){
1103
    COMPAT_CLOSE(*sock);
1104
    *sock = INVALID_SOCKET;
1105
    return MOSQ_ERR_ERRNO;
1106
  }
1107
#endif
1108
0
  return MOSQ_ERR_SUCCESS;
1109
0
}
1110
1111
1112
#ifndef WITH_BROKER
1113
1114
1115
int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW)
1116
{
1117
#ifdef WIN32
1118
  int family[2] = {AF_INET, AF_INET6};
1119
  int i;
1120
  struct sockaddr_storage ss;
1121
  struct sockaddr_in *sa = (struct sockaddr_in *)&ss;
1122
  struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&ss;
1123
  socklen_t ss_len;
1124
  mosq_sock_t spR, spW;
1125
1126
  mosq_sock_t listensock;
1127
1128
  *pairR = INVALID_SOCKET;
1129
  *pairW = INVALID_SOCKET;
1130
1131
  for(i=0; i<2; i++){
1132
    memset(&ss, 0, sizeof(ss));
1133
    if(family[i] == AF_INET){
1134
      sa->sin_family = family[i];
1135
      sa->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1136
      sa->sin_port = 0;
1137
      ss_len = sizeof(struct sockaddr_in);
1138
    }else if(family[i] == AF_INET6){
1139
      sa6->sin6_family = family[i];
1140
      sa6->sin6_addr = in6addr_loopback;
1141
      sa6->sin6_port = 0;
1142
      ss_len = sizeof(struct sockaddr_in6);
1143
    }else{
1144
      return MOSQ_ERR_INVAL;
1145
    }
1146
1147
    listensock = socket(family[i], SOCK_STREAM, IPPROTO_TCP);
1148
    if(listensock == -1){
1149
      continue;
1150
    }
1151
1152
    if(bind(listensock, (struct sockaddr *)&ss, ss_len) == -1){
1153
      COMPAT_CLOSE(listensock);
1154
      continue;
1155
    }
1156
1157
    if(listen(listensock, 1) == -1){
1158
      COMPAT_CLOSE(listensock);
1159
      continue;
1160
    }
1161
    memset(&ss, 0, sizeof(ss));
1162
    ss_len = sizeof(ss);
1163
    if(getsockname(listensock, (struct sockaddr *)&ss, &ss_len) < 0){
1164
      COMPAT_CLOSE(listensock);
1165
      continue;
1166
    }
1167
1168
    if(family[i] == AF_INET){
1169
      sa->sin_family = family[i];
1170
      sa->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1171
      ss_len = sizeof(struct sockaddr_in);
1172
    }else if(family[i] == AF_INET6){
1173
      sa6->sin6_family = family[i];
1174
      sa6->sin6_addr = in6addr_loopback;
1175
      ss_len = sizeof(struct sockaddr_in6);
1176
    }
1177
1178
    spR = socket(family[i], SOCK_STREAM, IPPROTO_TCP);
1179
    if(spR == -1){
1180
      COMPAT_CLOSE(listensock);
1181
      continue;
1182
    }
1183
    if(net__socket_nonblock(&spR)){
1184
      COMPAT_CLOSE(listensock);
1185
      continue;
1186
    }
1187
    if(connect(spR, (struct sockaddr *)&ss, ss_len) < 0){
1188
      WINDOWS_SET_ERRNO();
1189
      if(errno != EINPROGRESS && errno != COMPAT_EWOULDBLOCK){
1190
        COMPAT_CLOSE(spR);
1191
        COMPAT_CLOSE(listensock);
1192
        continue;
1193
      }
1194
    }
1195
    spW = accept(listensock, NULL, 0);
1196
    if(spW == -1){
1197
      WINDOWS_SET_ERRNO();
1198
      if(errno != EINPROGRESS && errno != COMPAT_EWOULDBLOCK){
1199
        COMPAT_CLOSE(spR);
1200
        COMPAT_CLOSE(listensock);
1201
        continue;
1202
      }
1203
    }
1204
1205
    if(net__socket_nonblock(&spW)){
1206
      COMPAT_CLOSE(spR);
1207
      COMPAT_CLOSE(listensock);
1208
      continue;
1209
    }
1210
    COMPAT_CLOSE(listensock);
1211
1212
    *pairR = spR;
1213
    *pairW = spW;
1214
    return MOSQ_ERR_SUCCESS;
1215
  }
1216
  return MOSQ_ERR_UNKNOWN;
1217
#else
1218
  int sv[2];
1219
1220
  *pairR = INVALID_SOCKET;
1221
  *pairW = INVALID_SOCKET;
1222
1223
  if(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1){
1224
    return MOSQ_ERR_ERRNO;
1225
  }
1226
  if(net__socket_nonblock(&sv[0])){
1227
    COMPAT_CLOSE(sv[1]);
1228
    return MOSQ_ERR_ERRNO;
1229
  }
1230
  if(net__socket_nonblock(&sv[1])){
1231
    COMPAT_CLOSE(sv[0]);
1232
    return MOSQ_ERR_ERRNO;
1233
  }
1234
  *pairR = sv[0];
1235
  *pairW = sv[1];
1236
  return MOSQ_ERR_SUCCESS;
1237
#endif
1238
}
1239
#endif
1240
1241
#ifndef WITH_BROKER
1242
1243
1244
void *mosquitto_ssl_get(struct mosquitto *mosq)
1245
{
1246
#ifdef WITH_TLS
1247
  return mosq->ssl;
1248
#else
1249
  UNUSED(mosq);
1250
1251
  return NULL;
1252
#endif
1253
}
1254
#endif