static void timeout(void *arg) { struct icem_comp *comp = arg; struct candpair *cp; tmr_start(&comp->tmr_ka, ICE_DEFAULT_Tr * 1000 + rand_u16() % 1000, timeout, comp); /* find selected candidate-pair */ cp = comp->cp_sel; if (!cp) return; (void)stun_indication(comp->icem->proto, comp->sock, &cp->rcand->addr, (cp->lcand->type == CAND_TYPE_RELAY) ? 4 : 0, STUN_METHOD_BINDING, NULL, 0, true, 0); }
/* Receive packet on the "relayed" address -- relay to the client */ static void relay_udp_recv(const struct sa *src, struct mbuf *mb, void *arg) { struct turnserver *turn = arg; struct channel *chan; int err = 0; ++turn->n_recv; chan = find_channel_peer(turn, src); if (chan) { uint16_t len = mbuf_get_left(mb); size_t start; if (mb->pos < 4) { DEBUG_WARNING("relay_udp_recv: mb pos < 4\n"); return; } mb->pos -= 4; start = mb->pos; (void)mbuf_write_u16(mb, htons(chan->nr)); (void)mbuf_write_u16(mb, htons(len)); mb->pos = start; err = udp_send(turn->us, &turn->cli, mb); } else { err = stun_indication(IPPROTO_UDP, turn->us, &turn->cli, 0, STUN_METHOD_DATA, NULL, 0, false, 2, STUN_ATTR_XOR_PEER_ADDR, src, STUN_ATTR_DATA, mb); } if (err) { DEBUG_WARNING("relay_udp_recv: error %m\n", err); } }