static int listen_handler(const struct pl *addrport, void *arg) { uint32_t sockbuf_size = *(uint32_t *)arg; struct udp_lstnr *ul = NULL; int err = ENOMEM; ul = mem_zalloc(sizeof(*ul), destructor); if (!ul) { restund_warning("udp listen error: %s\n", strerror(err)); goto out; } list_append(&lstnrl, &ul->le, ul); err = sa_decode(&ul->bnd_addr, addrport->p, addrport->l); if (err || sa_is_any(&ul->bnd_addr) || !sa_port(&ul->bnd_addr)) { restund_warning("bad udp_listen directive: '%r'\n", addrport); err = EINVAL; goto out; } err = udp_listen(&ul->us, &ul->bnd_addr, udp_recv, ul); if (err) { restund_warning("udp listen %J: %s\n", &ul->bnd_addr, strerror(err)); goto out; } if (sockbuf_size > 0) (void)udp_sockbuf_set(ul->us, sockbuf_size); restund_debug("udp listen: %J\n", &ul->bnd_addr); out: if (err) mem_deref(ul); return err; }
static int start(struct allocation *alloc) { struct sa laddr; int err = 0; if (!alloc) return EINVAL; sa_init(&laddr, sa_af(&alloc->srv)); switch (alloc->proto) { case IPPROTO_UDP: err = udp_listen(&alloc->us, &laddr, udp_recv, alloc); if (err) { re_fprintf(stderr, "allocation: failed to" " create UDP socket" " (%m)\n", err); goto out; } udp_sockbuf_set(alloc->us, 524288); if (alloc->secure) { /* note: re-using UDP socket for DTLS-traffic */ err = dtls_listen(&alloc->dtls_sock, NULL, alloc->us, 2, DTLS_LAYER, NULL, NULL); if (err) { re_fprintf(stderr, "dtls_listen error: %m\n", err); goto out; } err = dtls_connect(&alloc->tlsc, alloc->tls, alloc->dtls_sock, &alloc->srv, dtls_estab_handler, dtls_recv_handler, dtls_close_handler, alloc); if (err) { re_fprintf(stderr, "dtls_connect error: %m\n", err); goto out; } } else { err = turnc_alloc(&alloc->turnc, NULL, IPPROTO_UDP, alloc->us, TURN_LAYER, &alloc->srv, alloc->user, alloc->pass, TURN_DEFAULT_LIFETIME, turnc_handler, alloc); if (err) { re_fprintf(stderr, "allocation: failed to" " create TURN client" " (%m)\n", err); goto out; } } break; case IPPROTO_TCP: err = tcp_connect(&alloc->tc, &alloc->srv, tcp_estab_handler, tcp_recv_handler, tcp_close_handler, alloc); if (err) break; if (alloc->secure) { err = tls_start_tcp(&alloc->tlsc, alloc->tls, alloc->tc, 0); if (err) break; } break; default: err = EPROTONOSUPPORT; goto out; } out: return err; }