/* shared between STUN and TURN */ static void tcp_estab_handler(void *arg) { struct candidate *cand = arg; int err; re_printf("TCP established to STUN/TURN-server\n"); switch (cand->type) { case TYPE_STUN: err = stun_request(NULL, cand->ag->stun, IPPROTO_TCP, cand->tc, NULL, 0, STUN_METHOD_BINDING, NULL, 0, false, stun_resp_handler, cand, 0); if (err) { re_printf("tcp: stun_request failed (%m)\n", err); } break; case TYPE_TURN: err = turnc_alloc(&cand->turnc, NULL, IPPROTO_TCP, cand->tc, LAYER_TURN, &cand->turn_srv, cand->ag->cli->param.username, cand->ag->cli->param.password, TURN_DEFAULT_LIFETIME, turnc_handler, cand); if (err) { re_printf("tcp: turn client: %m\n", err); } break; } }
static int media_start(struct mnat_sess *sess, struct mnat_media *m) { int err = 0; if (m->sock1) { err |= turnc_alloc(&m->turnc1, NULL, m->proto, m->sock1, LAYER, &sess->srv, sess->user, sess->pass, TURN_DEFAULT_LIFETIME, turn_handler1, m); } if (m->sock2) { err |= turnc_alloc(&m->turnc2, NULL, m->proto, m->sock2, LAYER, &sess->srv, sess->user, sess->pass, TURN_DEFAULT_LIFETIME, turn_handler2, m); } return err; }
static void tcp_estab_handler(void *arg) { struct allocation *alloc = arg; int err; alloc->mb = mem_deref(alloc->mb); err = turnc_alloc(&alloc->turnc, NULL, IPPROTO_TCP, alloc->tc, 0, &alloc->srv, alloc->user, alloc->pass, TURN_DEFAULT_LIFETIME, turnc_handler, alloc); if (err) alloc->alloch(err, 0, NULL, NULL, NULL, alloc->arg); }
static int gather_relay2(struct candidate *cand, int turn_proto) { struct ice_lcand *base = cand->base; int err; switch (turn_proto) { case IPPROTO_UDP: /* the TURN-client must be created using the UDP-socket * of the base candidate */ err = turnc_alloc(&cand->turnc, NULL, turn_proto, base->us, LAYER_TURN, &cand->turn_srv, cand->ag->cli->param.username, cand->ag->cli->param.password, TURN_DEFAULT_LIFETIME, turnc_handler, cand); if (err) { re_printf("turn client: %m\n", err); } break; case IPPROTO_TCP: re_printf("TURN-TCP -- connecting to %J ..\n", &cand->turn_srv); /* NOTE: we are connecting _from_ an ephemeral port, * since we might have Zero TCP-candidates */ err = tcp_connect(&cand->tc, &cand->turn_srv, tcp_estab_handler, tcp_recv_handler, tcp_close_handler, cand); if (err) { re_printf("tcp_connect error (%m)\n", err); return err; } break; default: return EPROTONOSUPPORT; } return 0; }
static int cand_gather_relayed(struct icem *icem, struct icem_comp *comp, const char *username, const char *password) { const int layer = icem->layer - 10; /* below ICE stack */ int err; if (comp->turnc) return EALREADY; err = turnc_alloc(&comp->turnc, stun_conf(icem->stun), icem->proto, comp->sock, layer, &icem->stun_srv, username, password, 60, turnc_handler, comp); if (err) return err; ++icem->nstun; return 0; }
void turn_start(const struct stun_conf *conf, int proto, const struct sa *srv, uint32_t lifetime) { int err; if (turnc.tc) goto err; err = turnc_alloc(&turnc.tc, conf, proto, turnc.us, 0, srv, turnc.username, turnc.password, lifetime, turnc_handler, NULL); if (err) { DEBUG_WARNING("turnc_alloc: %s\n", err); goto err; } return; err: req.f.ar = false; }
static void dtls_estab_handler(void *arg) { struct allocation *alloc = arg; int err; re_printf("allocation: DTLS established\n"); err = turnc_alloc(&alloc->turnc, NULL, STUN_TRANSP_DTLS, alloc->tlsc, 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; } out: if (err) alloc->alloch(err, 0, NULL, NULL, NULL, alloc->arg); }
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; }