Changeset 1850 for pjproject/trunk
- Timestamp:
- Mar 8, 2008 12:54:04 AM (17 years ago)
- Location:
- pjproject/trunk/pjnath
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/build/pjturn_srv.dsp
r1812 r1850 88 88 # Begin Source File 89 89 90 SOURCE="..\src\pjturn-srv\allocation.c" 91 # End Source File 92 # Begin Source File 93 90 94 SOURCE="..\src\pjturn-srv\listener_udp.c" 91 95 # End Source File -
pjproject/trunk/pjnath/include/pjnath/stun_msg.h
r1811 r1850 68 68 69 69 /** 70 * STUN/TURN Send Indicationas defined by draft-ietf-behave-turn70 * STUN/TURN Refresh method as defined by draft-ietf-behave-turn 71 71 */ 72 72 PJ_STUN_REFRESH_METHOD = 4, 73 74 /** 75 * STUN/TURN Send indication as defined by draft-ietf-behave-turn 76 */ 77 PJ_STUN_SEND_METHOD = 6, 78 79 /** 80 * STUN/TURN Data indication as defined by draft-ietf-behave-turn 81 */ 82 PJ_STUN_DATA_METHOD = 7, 83 84 /** 85 * STUN/TURN ChannelBind as defined by draft-ietf-behave-turn 86 */ 87 PJ_STUN_CHANNEL_BIND_METHOD = 9, 73 88 74 89 /** … … 177 192 PJ_STUN_BINDING_ERROR_RESPONSE = 0x0111, 178 193 194 179 195 /** 180 196 * STUN SHARED-SECRET reqeust. … … 192 208 PJ_STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112, 193 209 210 194 211 /** 195 212 * STUN/TURN Allocate Request … … 207 224 PJ_STUN_ALLOCATE_ERROR_RESPONSE = 0x0113, 208 225 226 209 227 /** 210 228 * STUN/TURN REFRESH Request … … 220 238 * Error response to STUN REFRESH request. 221 239 */ 222 PJ_STUN_REFRESH_ERROR_RESPONSE = 0x0114 240 PJ_STUN_REFRESH_ERROR_RESPONSE = 0x0114, 241 242 243 /** 244 * TURN Send indication 245 */ 246 PJ_STUN_SEND_INDICATION = 0x0016, 247 248 249 /** 250 * TURN Data indication 251 */ 252 PJ_STUN_DATA_INDICATION = 0x0017, 253 254 255 /** 256 * STUN/TURN ChannelBind Request 257 */ 258 PJ_STUN_CHANNEL_BIND_REQUEST = 0x0009, 259 260 /** 261 * Successful response to STUN ChannelBind request 262 */ 263 PJ_STUN_CHANNEL_BIND_RESPONSE = 0x0109, 264 265 /** 266 * Error response to STUN ChannelBind request. 267 */ 268 PJ_STUN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119 223 269 224 270 } pj_stun_msg_type; … … 948 994 * number is returned in host byte order. 949 995 */ 950 #define PJ_STUN_GET_RPP_PORT(u32) pj_nto ns((pj_uint16_t)(u32 & 0x0000FFFFL))996 #define PJ_STUN_GET_RPP_PORT(u32) pj_ntohs((pj_uint16_t)(u32 & 0x0000FFFFL)) 951 997 952 998 /** -
pjproject/trunk/pjnath/src/pjnath/stun_msg.c
r1811 r1850 38 38 "Unknown", /* 0 */ 39 39 "Binding", /* 1 */ 40 "Shared 40 "SharedSecret", /* 2 */ 41 41 "Allocate", /* 3 */ 42 42 "Refresh", /* 4 */ 43 "???", /* 5 */ 44 "Send", /* 6 */ 45 "Data", /* 7 */ 46 "???", /* 8 */ 47 "ChannelBind", /* 9 */ 43 48 }; 44 49 -
pjproject/trunk/pjnath/src/pjturn-srv/server.c
r1812 r1850 36 36 37 37 38 /* Globals */39 PJ_DEF_DATA(int) PJTURN_TP_UDP = 1;40 PJ_DEF_DATA(int) PJTURN_TP_TCP = 2;41 PJ_DEF_DATA(int) PJTURN_TP_TLS = 3;42 43 38 /* Prototypes */ 44 39 static pj_status_t on_tx_stun_msg( pj_stun_session *sess, … … 54 49 unsigned src_addr_len); 55 50 51 /* 52 * Get transport type name. 53 */ 54 PJ_DEF(const char*) pjturn_tp_type_name(int tp_type) 55 { 56 /* Must be 3 characters long! */ 57 if (tp_type == PJTURN_TP_UDP) 58 return "UDP"; 59 else if (tp_type == PJTURN_TP_TCP) 60 return "TCP"; 61 else 62 return "???"; 63 } 56 64 57 65 /* … … 98 106 srv->tables.alloc = pj_hash_create(pool, MAX_CLIENTS); 99 107 srv->tables.res = pj_hash_create(pool, MAX_CLIENTS); 100 srv->tables.peer = pj_hash_create(pool, MAX_CLIENTS*MAX_PEERS_PER_CLIENT);101 108 102 109 /* Init ports settings */ … … 162 169 lis->id = index; 163 170 srv->core.lis_cnt++; 171 172 return PJ_SUCCESS; 173 } 174 175 /** 176 * Register an allocation. 177 */ 178 PJ_DEF(pj_status_t) pjturn_srv_register_allocation(pjturn_srv *srv, 179 pjturn_allocation *alloc) 180 { 181 /* Add to hash tables */ 182 pj_lock_acquire(srv->core.lock); 183 pj_hash_set(alloc->pool, srv->tables.alloc, 184 &alloc->hkey, sizeof(alloc->hkey), 0, alloc); 185 pj_hash_set(alloc->pool, srv->tables.res, 186 &alloc->relay.hkey, sizeof(alloc->relay.hkey), 0, 187 &alloc->relay); 188 pj_lock_release(srv->core.lock); 189 190 return PJ_SUCCESS; 191 } 192 193 /** 194 * Unregister an allocation. 195 */ 196 PJ_DEF(pj_status_t) pjturn_srv_unregister_allocation(pjturn_srv *srv, 197 pjturn_allocation *alloc) 198 { 199 /* Unregister from hash tables */ 200 pj_lock_acquire(srv->core.lock); 201 pj_hash_set(alloc->pool, srv->tables.alloc, 202 &alloc->hkey, sizeof(alloc->hkey), 0, NULL); 203 pj_hash_set(alloc->pool, srv->tables.res, 204 &alloc->relay.hkey, sizeof(alloc->relay.hkey), 0, NULL); 205 pj_lock_release(srv->core.lock); 164 206 165 207 return PJ_SUCCESS; … … 185 227 186 228 /* Create and send error response */ 187 static pj_status_t respond_error(pj_stun_sess *sess, const pj_stun_msg *req, 188 pj_bool_t cache, int code, const char *err_msg, 189 const pj_sockaddr_t *addr, unsigned addr_len) 229 static pj_status_t respond_error(pj_stun_session *sess, const pj_stun_msg *req, 230 pj_bool_t cache, int code, const char *errmsg, 231 const pj_sockaddr_t *dst_addr, 232 unsigned addr_len) 190 233 { 191 234 pj_status_t status; … … 194 237 195 238 status = pj_stun_session_create_res(sess, req, 196 code, (err _msg?pj_cstr(&reason,err_msg):NULL),239 code, (errmsg?pj_cstr(&reason,errmsg):NULL), 197 240 &tdata); 198 241 if (status != PJ_SUCCESS) 199 return stat ys;242 return status; 200 243 201 244 status = pj_stun_session_send_msg(sess, cache, dst_addr, addr_len, tdata); … … 221 264 222 265 /* Get BANDWIDTH attribute, if any. */ 223 attr_bw = pj_stun_msg_find_attr(msg, PJ_STUN_BANDWIDTH_ATTR, 0); 266 attr_bw = (pj_stun_uint_attr*) 267 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_BANDWIDTH, 0); 224 268 if (attr_bw) { 225 269 cfg->bandwidth = attr_bw->value; … … 230 274 /* Check if we can satisfy the bandwidth */ 231 275 if (cfg->bandwidth > MAX_CLIENT_BANDWIDTH) { 232 respond_error(sess, msg, PJ_FALSE,276 respond_error(sess, req, PJ_FALSE, 233 277 PJ_STUN_SC_ALLOCATION_QUOTA_REACHED, 234 278 "Invalid bandwidth", src_addr, src_addr_len); … … 237 281 238 282 /* Get REQUESTED-TRANSPORT attribute, is any */ 239 attr_req_tp = pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_REQ_TRANSPORT, 0); 283 attr_req_tp = (pj_stun_uint_attr*) 284 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REQ_TRANSPORT, 0); 240 285 if (attr_req_tp) { 241 286 cfg->tp_type = PJ_STUN_GET_RT_PROTO(attr_req_tp->value); … … 246 291 /* Can only support UDP for now */ 247 292 if (cfg->tp_type != PJTURN_TP_UDP) { 248 respond_error(sess, msg, PJ_FALSE,293 respond_error(sess, req, PJ_FALSE, 249 294 PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO, 250 295 NULL, src_addr, src_addr_len); … … 253 298 254 299 /* Get REQUESTED-IP attribute, if any */ 255 attr_req_ip = pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_REQ_IP, 0); 300 attr_req_ip = (pj_stun_sockaddr_attr*) 301 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REQ_IP, 0); 256 302 if (attr_req_ip) { 257 pj_ memcpy(&cfg->addr, &attr_req_ip->sockaddr,258 sizeof(attr_req_ip->sockaddr));303 pj_sockaddr_print(&attr_req_ip->sockaddr, cfg->addr, 304 sizeof(cfg->addr), 0); 259 305 } 260 306 261 307 /* Get REQUESTED-PORT-PROPS attribute, if any */ 262 attr_rpp = pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_REQ_PORT_PROPS, 0); 308 attr_rpp = (pj_stun_uint_attr*) 309 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REQ_PORT_PROPS, 0); 263 310 if (attr_rpp) { 264 311 cfg->rpp_bits = PJ_STUN_GET_RPP_BITS(attr_rpp->value); … … 270 317 271 318 /* Get LIFETIME attribute */ 272 attr_lifetime = pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_LIFETIME, 0); 319 attr_lifetime = (pj_stun_uint_attr*) 320 pj_stun_msg_find_attr(req, PJ_STUN_ATTR_LIFETIME, 0); 273 321 if (attr_lifetime) { 274 322 cfg->lifetime = attr_lifetime->value; 275 323 if (cfg->lifetime < MIN_LIFETIME || cfg->lifetime > MAX_LIFETIME) { 276 respond_error(sess, msg, PJ_FALSE,324 respond_error(sess, req, PJ_FALSE, 277 325 PJ_STUN_SC_BAD_REQUEST, 278 326 "Invalid LIFETIME value", src_addr, … … 296 344 { 297 345 pjturn_listener *listener; 346 pjturn_srv *srv; 298 347 pjturn_allocation_req req; 348 pjturn_allocation *alloc; 349 pj_stun_tx_data *tdata; 299 350 pj_status_t status; 300 351 301 352 listener = (pjturn_listener*) pj_stun_session_get_user_data(sess); 353 srv = listener->server; 302 354 303 355 /* Handle strayed REFRESH request */ … … 322 374 return status; 323 375 324 /* Ready to allocate now */ 325 376 /* Create new allocation. The relay resource will be allocated 377 * in this function. 378 */ 379 status = pjturn_allocation_create(listener, src_addr, src_addr_len, 380 msg, &req, &alloc); 381 if (status != PJ_SUCCESS) { 382 char errmsg[PJ_ERR_MSG_SIZE]; 383 384 pj_strerror(status, errmsg, sizeof(errmsg)); 385 return respond_error(sess, msg, PJ_FALSE, PJ_STUN_SC_SERVER_ERROR, 386 errmsg, src_addr, src_addr_len); 387 } 388 389 /* Respond the original ALLOCATE request */ 390 status = pj_stun_session_create_res(srv->core.stun_sess[listener->id], 391 msg, 0, NULL, &tdata); 392 if (status != PJ_SUCCESS) { 393 char errmsg[PJ_ERR_MSG_SIZE]; 394 395 pjturn_allocation_destroy(alloc); 396 397 pj_strerror(status, errmsg, sizeof(errmsg)); 398 return respond_error(sess, msg, PJ_FALSE, PJ_STUN_SC_SERVER_ERROR, 399 errmsg, src_addr, src_addr_len); 400 } 401 402 /* Add RELAYED-ADDRESS attribute */ 403 pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 404 PJ_STUN_ATTR_RELAY_ADDR, PJ_TRUE, 405 &alloc->relay.hkey.addr, 406 pj_sockaddr_get_len(&alloc->relay.hkey.addr)); 407 408 /* Add LIFETIME. */ 409 pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, 410 PJ_STUN_ATTR_LIFETIME, 411 (unsigned)alloc->relay.lifetime); 412 413 /* Add BANDWIDTH */ 414 pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, 415 PJ_STUN_ATTR_BANDWIDTH, 416 alloc->bandwidth); 417 418 /* Add RESERVATION-TOKEN */ 419 PJ_TODO(ADD_RESERVATION_TOKEN); 420 421 /* Add XOR-MAPPED-ADDRESS */ 422 pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 423 PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, 424 &alloc->hkey.clt_addr, 425 pj_sockaddr_get_len(&alloc->hkey.clt_addr)); 426 427 /* Send the response */ 428 pj_stun_session_send_msg(srv->core.stun_sess[listener->id], PJ_TRUE, 429 src_addr, src_addr_len, tdata); 430 431 /* Done. */ 432 return PJ_SUCCESS; 326 433 } 327 434 … … 331 438 pjturn_pkt *pkt) 332 439 { 333 pj_stun_msg *req, *res;334 440 unsigned options, lis_id; 335 441 pj_status_t status; … … 392 498 */ 393 499 if (alloc) { 394 pjturn_allocation_on_rx_ pkt(alloc, pkt);500 pjturn_allocation_on_rx_client_pkt(alloc, pkt); 395 501 } else { 396 502 /* Otherwise this is a new client */ -
pjproject/trunk/pjnath/src/pjturn-srv/turn.h
r1812 r1850 34 34 #define PJTURN_NO_TIMEOUT ((long)0x7FFFFFFF) 35 35 #define PJTURN_MAX_PKT_LEN 3000 36 #define PJTURN_PERM_TIMEOUT 300 37 #define PJTURN_CHANNEL_TIMEOUT 600 36 38 37 39 /** Transport types */ … … 41 43 }; 42 44 45 /** 46 * Get transport type name string. 47 */ 48 PJ_DECL(const char*) pjturn_tp_type_name(int tp_type); 43 49 44 50 /** … … 55 61 /** Transport/relay address */ 56 62 pj_sockaddr addr; 57 } key; 58 59 /** Pool for this resource. */ 60 pj_pool_t *pool; 61 62 /** Mutex */ 63 pj_lock_t *lock; 63 } hkey; 64 64 65 65 /** Allocation who requested or reserved this resource. */ 66 66 pjturn_allocation *allocation; 67 67 68 /** Time when this resource times out */69 pj_time_val timeout;70 71 68 /** Username used in credential */ 72 69 pj_str_t user; … … 75 72 pj_str_t realm; 76 73 77 /** Transport/relay socket */ 78 pj_sock_t sock; 74 /** Lifetime, in seconds. */ 75 unsigned lifetime; 76 77 /** Relay/allocation expiration time */ 78 pj_time_val expiry; 79 80 /** Timeout timer entry */ 81 pj_timer_entry timer; 82 83 /** Transport. */ 84 struct { 85 /** Transport/relay socket */ 86 pj_sock_t sock; 87 88 /** Transport/relay ioqueue */ 89 pj_ioqueue_key_t *key; 90 91 /** Read operation key. */ 92 pj_ioqueue_op_key_t read_key; 93 94 /** The incoming packet buffer */ 95 char rx_pkt[PJTURN_MAX_PKT_LEN]; 96 97 /** Source address of the packet. */ 98 pj_sockaddr src_addr; 99 100 /** Source address length */ 101 int src_addr_len; 102 103 /** The outgoing packet buffer. This must be 3wbit aligned. */ 104 char tx_pkt[PJTURN_MAX_PKT_LEN+4]; 105 } tp; 79 106 }; 80 107 … … 105 132 106 133 /** Requested IP */ 107 pj_sockaddr addr;134 char addr[PJ_INET6_ADDRSTRLEN]; 108 135 109 136 /** Requested bandwidth */ … … 128 155 { 129 156 /** Hash table key to identify client. */ 130 pjturn_allocation_key key;157 pjturn_allocation_key hkey; 131 158 132 159 /** Pool for this allocation. */ 133 160 pj_pool_t *pool; 134 161 162 /** Object name for logging identification */ 163 char *obj_name; 164 165 /** Client info (IP address and port) */ 166 char info[80]; 167 135 168 /** Mutex */ 136 169 pj_lock_t *lock; … … 148 181 pjturn_relay_res *resv; 149 182 150 }; 183 /** Requested bandwidth */ 184 unsigned bandwidth; 185 186 /** STUN session for this client */ 187 pj_stun_session *sess; 188 189 /** Peer hash table (keyed by peer address) */ 190 pj_hash_table_t *peer_table; 191 192 /** Channel hash table (keyed by channel number) */ 193 pj_hash_table_t *ch_table; 194 }; 195 196 197 /** 198 * This structure describes the hash table key to lookup TURN 199 * permission. 200 */ 201 typedef struct pjturn_permission_key 202 { 203 /** Peer address. */ 204 pj_sockaddr peer_addr; 205 206 } pjturn_permission_key; 151 207 152 208 … … 157 213 { 158 214 /** Hash table key */ 159 struct { 160 /** Transport type. */ 161 pj_uint16_t tp_type; 162 163 /** Transport socket. If TCP is used, the value will be the actual 164 * TCP socket. If UDP is used, the value will be the relay address 165 */ 166 pj_sock_t sock; 167 168 /** Peer address. */ 169 pj_sockaddr peer_addr; 170 } key; 171 172 /** Pool for this permission. */ 173 pj_pool_t *pool; 174 175 /** Mutex */ 176 pj_lock_t *lock; 215 pjturn_permission_key hkey; 216 217 /** Transport socket. If TCP is used, the value will be the actual 218 * TCP socket. If UDP is used, the value will be the relay address 219 */ 220 pj_sock_t sock; 177 221 178 222 /** TURN allocation that owns this permission/channel */ … … 184 228 pj_uint16_t channel; 185 229 186 /** Permission timeout. */ 187 pj_time_val timeout; 188 }; 189 190 /** 191 * Handle incoming packet. 192 */ 193 PJ_DECL(void) pjturn_allocation_on_rx_pkt(pjturn_allocation *alloc, 194 pjturn_pkt *pkt); 195 230 /** Permission expiration time. */ 231 pj_time_val expiry; 232 }; 233 234 /** 235 * Create new allocation. 236 */ 237 PJ_DECL(pj_status_t) pjturn_allocation_create(pjturn_listener *listener, 238 const pj_sockaddr_t *src_addr, 239 unsigned src_addr_len, 240 const pj_stun_msg *msg, 241 const pjturn_allocation_req *req, 242 pjturn_allocation **p_alloc); 243 /** 244 * Destroy allocation. 245 */ 246 PJ_DECL(void) pjturn_allocation_destroy(pjturn_allocation *alloc); 247 248 /** 249 * Create relay. 250 */ 251 PJ_DECL(pj_status_t) pjturn_allocation_create_relay(pjturn_srv *srv, 252 pjturn_allocation *alloc, 253 const pj_stun_msg *msg, 254 const pjturn_allocation_req *req, 255 pjturn_relay_res *relay); 256 257 /** 258 * Handle incoming packet from client. 259 */ 260 PJ_DECL(void) pjturn_allocation_on_rx_client_pkt(pjturn_allocation *alloc, 261 pjturn_pkt *pkt); 196 262 197 263 /****************************************************************************/ … … 251 317 pjturn_listener *listener; 252 318 253 /** Packet buffer . */319 /** Packet buffer (must be 32bit aligned). */ 254 320 pj_uint8_t pkt[PJTURN_MAX_PKT_LEN]; 255 321 … … 358 424 pj_hash_table_t *res; 359 425 360 /** Permission hash table, indexed by transport type, socket handle,361 * and peer address.362 */363 pj_hash_table_t *peer;364 365 426 } tables; 366 427 … … 408 469 409 470 /** 471 * Register an allocation. 472 */ 473 PJ_DECL(pj_status_t) pjturn_srv_register_allocation(pjturn_srv *srv, 474 pjturn_allocation *alloc); 475 476 /** 477 * Unregister an allocation. 478 */ 479 PJ_DECL(pj_status_t) pjturn_srv_unregister_allocation(pjturn_srv *srv, 480 pjturn_allocation *alloc); 481 482 /** 410 483 * This callback is called by UDP listener on incoming packet. 411 484 */
Note: See TracChangeset
for help on using the changeset viewer.