/* TODO([email protected]): We currently don't support channels. We might in the future. Mozilla bug 857736 */ int nr_turn_client_send_indication(nr_turn_client_ctx *ctx, const UCHAR *msg, size_t len, int flags, nr_transport_addr *remote_addr) { int r,_status; nr_stun_client_send_indication_params params = { { 0 } }; nr_stun_message *ind = 0; if (ctx->state != NR_TURN_CLIENT_STATE_ALLOCATED) ABORT(R_FAILED); r_log(NR_LOG_TURN, LOG_DEBUG, "TURN(%s): Send indication len=%zu", ctx->label, len); if ((r=nr_turn_client_ensure_perm(ctx, remote_addr))) ABORT(r); if ((r=nr_transport_addr_copy(¶ms.remote_addr, remote_addr))) ABORT(r); params.data.data = (UCHAR*)msg; params.data.len = len; if ((r=nr_stun_build_send_indication(¶ms, &ind))) ABORT(r); if ((r=nr_turn_client_send_stun_request(ctx, ind, flags))) ABORT(r); _status=0; abort: nr_stun_message_destroy(&ind); return(_status); }
/* TODO([email protected]): We currently don't support channels. We might in the future. Mozilla bug 857736 */ int nr_turn_client_send_indication(nr_turn_client_ctx *ctx, const UCHAR *msg, size_t len, int flags, nr_transport_addr *remote_addr) { int r,_status; nr_stun_client_send_indication_params params = { { 0 } }; nr_stun_message *ind = 0; if (ctx->state != NR_TURN_CLIENT_STATE_ALLOCATED) ABORT(R_FAILED); r_log(NR_LOG_TURN, LOG_DEBUG, "TURN(%s): Send indication len=%zu", ctx->label, len); if ((r=nr_turn_client_ensure_perm(ctx, remote_addr))) ABORT(r); if ((r=nr_transport_addr_copy(¶ms.remote_addr, remote_addr))) ABORT(r); params.data.data = (UCHAR*)msg; params.data.len = len; if ((r=nr_stun_build_send_indication(¶ms, &ind))) ABORT(r); if ((r=nr_stun_encode_message(ind))) ABORT(r); if ((r=nr_socket_sendto(ctx->sock, ind->buffer, ind->length, flags, &ctx->turn_server_addr))) { r_log(NR_LOG_TURN, LOG_WARNING, "TURN(%s): Failed sending send indication", ctx->label); ABORT(r); } _status=0; abort: RFREE(ind); return(_status); }
int nr_turn_client_parse_data_indication(nr_turn_client_ctx *ctx, nr_transport_addr *source_addr, UCHAR *msg, size_t len, UCHAR *newmsg, size_t *newlen, size_t newsize, nr_transport_addr *remote_addr) { int r,_status; nr_stun_message *ind=0; nr_stun_message_attribute *attr; nr_turn_permission *perm; if (nr_transport_addr_cmp(&ctx->turn_server_addr, source_addr, NR_TRANSPORT_ADDR_CMP_MODE_ALL)) { r_log(NR_LOG_TURN, LOG_WARNING, "TURN(%s): Indication from unexpected source addr %s (expected %s)", ctx->label, source_addr->as_string, ctx->turn_server_addr.as_string); ABORT(R_REJECTED); } if ((r=nr_stun_message_create2(&ind, msg, len))) ABORT(r); if ((r=nr_stun_decode_message(ind, 0, 0))) ABORT(r); if (ind->header.type != NR_STUN_MSG_DATA_INDICATION) ABORT(R_BAD_ARGS); if (!nr_stun_message_has_attribute(ind, NR_STUN_ATTR_XOR_PEER_ADDRESS, &attr)) ABORT(R_BAD_ARGS); if ((r=nr_turn_permission_find(ctx, &attr->u.xor_mapped_address.unmasked, &perm))) { if (r == R_NOT_FOUND) { r_log(NR_LOG_TURN, LOG_WARNING, "TURN(%s): Indication from peer addr %s with no permission", ctx->label, attr->u.xor_mapped_address.unmasked.as_string); } ABORT(r); } if ((r=nr_transport_addr_copy(remote_addr, &attr->u.xor_mapped_address.unmasked))) ABORT(r); #if REFRESH_RESERVATION_ON_RECV if ((r=nr_turn_client_ensure_perm(ctx, remote_addr))) { ABORT(r); } #endif if (!nr_stun_message_has_attribute(ind, NR_STUN_ATTR_DATA, &attr)) { ABORT(R_BAD_DATA); } assert(newsize >= attr->u.data.length); if (newsize < attr->u.data.length) ABORT(R_BAD_ARGS); memcpy(newmsg, attr->u.data.data, attr->u.data.length); *newlen = attr->u.data.length; _status=0; abort: nr_stun_message_destroy(&ind); return(_status); }