Changeset 5987 for pjproject/trunk/pjnath/src/pjnath/turn_session.c
- Timestamp:
- May 14, 2019 9:31:39 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/src/pjnath/turn_session.c
r5983 r5987 104 104 }; 105 105 106 struct conn_bind_t 107 { 108 pj_uint32_t id; /* Connection ID. */ 109 pj_sockaddr peer_addr; /* Peer address. */ 110 unsigned peer_addr_len; 111 }; 106 112 107 113 /* The TURN client session structure */ … … 209 215 { 210 216 pj_bzero(prm, sizeof(*prm)); 217 prm->peer_conn_type = PJ_TURN_TP_UDP; 211 218 } 212 219 … … 724 731 sess->state<=PJ_TURN_STATE_RESOLVED, 725 732 PJ_EINVALIDOP); 733 PJ_ASSERT_RETURN(param->peer_conn_type == PJ_TURN_TP_UDP || 734 param->peer_conn_type == PJ_TURN_TP_TCP, 735 PJ_EINVAL); 726 736 727 737 /* Verify address family in allocation param */ … … 761 771 pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, 762 772 PJ_STUN_ATTR_REQ_TRANSPORT, 763 PJ_STUN_SET_RT_PROTO( PJ_TURN_TP_UDP));773 PJ_STUN_SET_RT_PROTO(param->peer_conn_type)); 764 774 765 775 /* Include BANDWIDTH if requested */ … … 999 1009 } 1000 1010 1011 /* If peer connection is TCP (RFC 6062), send it directly */ 1012 if (sess->alloc_param.peer_conn_type == PJ_TURN_TP_TCP) { 1013 status = sess->cb.on_send_pkt(sess, pkt, pkt_len, addr, addr_len); 1014 goto on_return; 1015 } 1016 1001 1017 /* See if the peer is bound to a channel number */ 1002 1018 ch = lookup_ch_by_addr(sess, addr, pj_sockaddr_get_len(addr), … … 1139 1155 1140 1156 /** 1141 * Notify TURN client session upon receiving a packet from server. 1142 * The packet maybe a STUN packet or ChannelData packet. 1143 */ 1157 * Send ConnectionBind request. 1158 */ 1159 PJ_DEF(pj_status_t) pj_turn_session_connection_bind( 1160 pj_turn_session *sess, 1161 pj_pool_t *pool, 1162 pj_uint32_t conn_id, 1163 const pj_sockaddr_t *peer_addr, 1164 unsigned addr_len) 1165 { 1166 pj_stun_tx_data *tdata; 1167 struct conn_bind_t *conn_bind; 1168 pj_status_t status; 1169 1170 PJ_ASSERT_RETURN(sess && pool && conn_id && peer_addr && addr_len, 1171 PJ_EINVAL); 1172 PJ_ASSERT_RETURN(sess->state == PJ_TURN_STATE_READY, PJ_EINVALIDOP); 1173 1174 pj_grp_lock_acquire(sess->grp_lock); 1175 1176 /* Create blank ConnectionBind request */ 1177 status = pj_stun_session_create_req(sess->stun, 1178 PJ_STUN_CONNECTION_BIND_REQUEST, 1179 PJ_STUN_MAGIC, NULL, &tdata); 1180 if (status != PJ_SUCCESS) 1181 goto on_return; 1182 1183 /* Add CONNECTION_ID attribute */ 1184 pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, 1185 PJ_STUN_ATTR_CONNECTION_ID, 1186 conn_id); 1187 1188 conn_bind = PJ_POOL_ZALLOC_T(pool, struct conn_bind_t); 1189 conn_bind->id = conn_id; 1190 pj_sockaddr_cp(&conn_bind->peer_addr, peer_addr); 1191 conn_bind->peer_addr_len = addr_len; 1192 1193 /* Send the request, associate connection data structure with tdata 1194 * for future reference when we receive the ConnectionBind response. 1195 */ 1196 status = pj_stun_session_send_msg(sess->stun, conn_bind, PJ_FALSE, 1197 PJ_FALSE, peer_addr, addr_len, tdata); 1198 1199 on_return: 1200 pj_grp_lock_release(sess->grp_lock); 1201 return status; 1202 } 1203 1144 1204 PJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess, 1145 1205 void *pkt, … … 1147 1207 pj_size_t *parsed_len) 1148 1208 { 1209 pj_turn_session_on_rx_pkt_param prm; 1210 pj_status_t status; 1211 1212 pj_bzero(&prm, sizeof(prm)); 1213 prm.pkt = pkt; 1214 prm.pkt_len = pkt_len; 1215 status = pj_turn_session_on_rx_pkt2(sess, &prm); 1216 if (status == PJ_SUCCESS && parsed_len) 1217 *parsed_len = prm.parsed_len; 1218 return status; 1219 } 1220 1221 /** 1222 * Notify TURN client session upon receiving a packet from server. 1223 * The packet maybe a STUN packet or ChannelData packet. 1224 */ 1225 PJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt2( 1226 pj_turn_session *sess, 1227 pj_turn_session_on_rx_pkt_param *prm) 1228 { 1149 1229 pj_bool_t is_stun; 1150 1230 pj_status_t status; … … 1161 1241 1162 1242 /* Quickly check if this is STUN message */ 1163 is_stun = ((((pj_uint8_t*)p kt)[0] & 0xC0) == 0);1243 is_stun = ((((pj_uint8_t*)prm->pkt)[0] & 0xC0) == 0); 1164 1244 1165 1245 if (is_stun) { 1166 1246 /* This looks like STUN, give it to the STUN session */ 1167 1247 unsigned options; 1248 const pj_sockaddr_t *src_addr = prm->src_addr? 1249 prm->src_addr:sess->srv_addr; 1250 unsigned src_addr_len = prm->src_addr_len? prm->src_addr_len: 1251 pj_sockaddr_get_len(sess->srv_addr); 1168 1252 1169 1253 options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK; 1170 1254 if (is_datagram) 1171 1255 options |= PJ_STUN_IS_DATAGRAM; 1172 status=pj_stun_session_on_rx_pkt(sess->stun, pkt, pkt_len, 1173 options, NULL, parsed_len, 1174 sess->srv_addr, 1175 pj_sockaddr_get_len(sess->srv_addr)); 1256 status=pj_stun_session_on_rx_pkt(sess->stun, prm->pkt, prm->pkt_len, 1257 options, NULL, &prm->parsed_len, 1258 src_addr, src_addr_len); 1176 1259 1177 1260 } else { … … 1180 1263 struct ch_t *ch; 1181 1264 1182 if (p kt_len < 4) {1183 if (parsed_len) *parsed_len = 0;1265 if (prm->pkt_len < 4) { 1266 prm->parsed_len = 0; 1184 1267 return PJ_ETOOSMALL; 1185 1268 } 1186 1269 1187 1270 /* Decode ChannelData packet */ 1188 pj_memcpy(&cd, p kt, sizeof(pj_turn_channel_data));1271 pj_memcpy(&cd, prm->pkt, sizeof(pj_turn_channel_data)); 1189 1272 cd.ch_number = pj_ntohs(cd.ch_number); 1190 1273 cd.length = pj_ntohs(cd.length); 1191 1274 1192 1275 /* Check that size is sane */ 1193 if (pkt_len < cd.length+sizeof(cd)) { 1194 if (parsed_len) { 1195 if (is_datagram) { 1196 /* Discard the datagram */ 1197 *parsed_len = pkt_len; 1198 } else { 1199 /* Insufficient fragment */ 1200 *parsed_len = 0; 1201 } 1276 if (prm->pkt_len < cd.length+sizeof(cd)) { 1277 if (is_datagram) { 1278 /* Discard the datagram */ 1279 prm->parsed_len = prm->pkt_len; 1280 } else { 1281 /* Insufficient fragment */ 1282 prm->parsed_len = 0; 1202 1283 } 1203 1284 status = PJ_ETOOSMALL; 1204 1285 goto on_return; 1205 1286 } else { 1206 if (parsed_len) { 1207 /* Apply padding too */ 1208 *parsed_len = ((cd.length + 3) & (~3)) + sizeof(cd); 1209 } 1287 /* Apply padding too */ 1288 prm->parsed_len = ((cd.length + 3) & (~3)) + sizeof(cd); 1210 1289 } 1211 1290 … … 1219 1298 /* Notify application */ 1220 1299 if (sess->cb.on_rx_data) { 1221 (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)p kt)+sizeof(cd),1300 (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)prm->pkt)+sizeof(cd), 1222 1301 cd.length, &ch->addr, 1223 1302 pj_sockaddr_get_len(&ch->addr)); … … 1643 1722 } 1644 1723 1724 } else if (method == PJ_STUN_CONNECTION_BIND_METHOD) { 1725 /* Handle ConnectionBind response */ 1726 struct conn_bind_t *conn_bind = (struct conn_bind_t*)token; 1727 1728 if (status != PJ_SUCCESS || 1729 !PJ_STUN_IS_SUCCESS_RESPONSE(response->hdr.type)) 1730 { 1731 pj_str_t reason = {0}; 1732 if (status == PJ_SUCCESS) { 1733 const pj_stun_errcode_attr *err_attr; 1734 err_attr = (const pj_stun_errcode_attr*) 1735 pj_stun_msg_find_attr(response, 1736 PJ_STUN_ATTR_ERROR_CODE, 0); 1737 if (err_attr) { 1738 status = PJ_STATUS_FROM_STUN_CODE(err_attr->err_code); 1739 reason = err_attr->reason; 1740 } else { 1741 status = PJNATH_EINSTUNMSG; 1742 } 1743 } 1744 pj_perror(1, sess->obj_name, status, "ConnectionBind failed: %.*s", 1745 (int)reason.slen, reason.ptr); 1746 } 1747 1748 /* Notify app */ 1749 if (sess->cb.on_connection_bind_status) { 1750 (*sess->cb.on_connection_bind_status) 1751 (sess, status, conn_bind->id, 1752 &conn_bind->peer_addr, conn_bind->peer_addr_len); 1753 } 1645 1754 } else { 1646 1755 PJ_LOG(4,(sess->obj_name, "Unexpected STUN %s response", … … 1675 1784 sess = (pj_turn_session*)pj_stun_session_get_user_data(stun); 1676 1785 1677 /* Expecting Data Indication only */ 1786 /* ConnectionAttempt Indication */ 1787 if (msg->hdr.type == PJ_STUN_CONNECTION_ATTEMPT_INDICATION) { 1788 pj_stun_uint_attr *connection_id_attr; 1789 1790 /* Get CONNECTION-ID attribute */ 1791 connection_id_attr = (pj_stun_uint_attr*) 1792 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_CONNECTION_ID, 0); 1793 1794 /* Get XOR-PEER-ADDRESS attribute */ 1795 peer_attr = (pj_stun_xor_peer_addr_attr*) 1796 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0); 1797 1798 /* Must have both XOR-PEER-ADDRESS and CONNECTION-ID attributes */ 1799 if (!peer_attr || !connection_id_attr) { 1800 PJ_LOG(4,(sess->obj_name, 1801 "Received ConnectionAttempt indication with missing " 1802 "attributes")); 1803 return PJ_EINVALIDOP; 1804 } 1805 1806 /* Notify application */ 1807 if (sess->cb.on_connection_attempt) { 1808 (*sess->cb.on_connection_attempt) 1809 (sess, 1810 connection_id_attr->value, 1811 &peer_attr->sockaddr, 1812 pj_sockaddr_get_len(&peer_attr->sockaddr)); 1813 } 1814 return PJ_SUCCESS; 1815 } 1816 1817 /* Next, expecting Data Indication only */ 1678 1818 if (msg->hdr.type != PJ_STUN_DATA_INDICATION) { 1679 1819 PJ_LOG(4,(sess->obj_name, "Unexpected STUN %s indication",
Note: See TracChangeset
for help on using the changeset viewer.