@@ -461,8 +461,14 @@ static void mdns_cb(struct mg_connection *c, int ev, void *ev_data) {
461
461
462
462
void mg_multicast_add(struct mg_connection *c, char *ip);
463
463
struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, char *name) {
464
+ char *mcast_url;
465
+ #if MG_ARCH == MG_ARCH_WIN32
466
+ mcast_url = "udp://0.0.0.0:5353";
467
+ #else
468
+ mcast_url = "udp://224.0.0.251:5353";
469
+ #endif
464
470
struct mg_connection *c =
465
- mg_listen(mgr, "udp://224.0.0.251:5353" , mdns_cb, name);
471
+ mg_listen(mgr, mcast_url , mdns_cb, name);
466
472
if (c != NULL) mg_multicast_add(c, (char *)"224.0.0.251");
467
473
return c;
468
474
}
@@ -8418,27 +8424,38 @@ bool mg_open_listener(struct mg_connection *c, const char *url) {
8418
8424
int rc, on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET;
8419
8425
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
8420
8426
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
8427
+ int sockopt = -1;
8421
8428
(void) on;
8422
8429
8430
+ #if defined(SO_EXCLUSIVEADDRUSE)
8431
+ if (proto == IPPROTO_UDP) {
8432
+ sockopt = SO_REUSEADDR;
8433
+ } else {
8434
+ sockopt = SO_EXCLUSIVEADDRUSE;
8435
+ }
8436
+ // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
8437
+ #elif defined(SO_REUSEADDR) && (!defined(LWIP_SOCKET) || SO_REUSE)
8438
+ sockopt = SO_REUSEADDR;
8439
+ // 1. SO_REUSEADDR semantics on UNIX and Windows is different. On
8440
+ // Windows, SO_REUSEADDR allows to bind a socket to a port without error
8441
+ // even if the port is already open by another program. This is not the
8442
+ // behavior SO_REUSEADDR was designed for, and leads to hard-to-track
8443
+ // failure scenarios.
8444
+ //
8445
+ // 2. For LWIP, SO_REUSEADDR should be explicitly enabled by defining
8446
+ // SO_REUSE = 1 in lwipopts.h, otherwise the code below will compile but
8447
+ // won't work! (setsockopt will return EINVAL)
8448
+ #endif
8449
+
8450
+ MG_INFO(("%d %d", proto, IPPROTO_UDP));
8451
+
8423
8452
if ((fd = socket(af, type, proto)) == MG_INVALID_SOCKET) {
8424
8453
MG_ERROR(("socket: %d", MG_SOCK_ERR(-1)));
8425
- #if defined(SO_EXCLUSIVEADDRUSE)
8426
- } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
8454
+ } else if ((sockopt != -1) && (rc = setsockopt(fd, SOL_SOCKET, sockopt,
8427
8455
(char *) &on, sizeof(on))) != 0) {
8428
- // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
8456
+ #if defined( SO_EXCLUSIVEADDRUSE)
8429
8457
MG_ERROR(("setsockopt(SO_EXCLUSIVEADDRUSE): %d %d", on, MG_SOCK_ERR(rc)));
8430
- #elif defined(SO_REUSEADDR) && (!defined(LWIP_SOCKET) || SO_REUSE)
8431
- } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
8432
- sizeof(on))) != 0) {
8433
- // 1. SO_REUSEADDR semantics on UNIX and Windows is different. On
8434
- // Windows, SO_REUSEADDR allows to bind a socket to a port without error
8435
- // even if the port is already open by another program. This is not the
8436
- // behavior SO_REUSEADDR was designed for, and leads to hard-to-track
8437
- // failure scenarios.
8438
- //
8439
- // 2. For LWIP, SO_REUSEADDR should be explicitly enabled by defining
8440
- // SO_REUSE = 1 in lwipopts.h, otherwise the code below will compile but
8441
- // won't work! (setsockopt will return EINVAL)
8458
+ #else
8442
8459
MG_ERROR(("setsockopt(SO_REUSEADDR): %d", MG_SOCK_ERR(rc)));
8443
8460
#endif
8444
8461
#if MG_IPV6_V6ONLY
0 commit comments