Changeset 92b42442 in mainline for uspace/srv/udp/assoc.c
- Timestamp:
- 2012-04-05T21:16:00Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7094e196
- Parents:
- ee603c4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/udp/assoc.c
ree603c4 r92b42442 51 51 FIBRIL_MUTEX_INITIALIZE(assoc_list_lock); 52 52 53 static udp_assoc_t *udp_assoc_find_ref(udp_sockpair_t *); 54 static int udp_assoc_queue_msg(udp_assoc_t *, udp_sockpair_t *, udp_msg_t *); 55 static bool udp_socket_match(udp_sock_t *, udp_sock_t *); 56 static bool udp_sockpair_match(udp_sockpair_t *, udp_sockpair_t *); 57 53 58 /** Create new association structure. 54 59 * … … 61 66 udp_assoc_t *assoc = NULL; 62 67 63 /* Allocate connection structure */68 /* Allocate association structure */ 64 69 assoc = calloc(1, sizeof(udp_assoc_t)); 65 70 if (assoc == NULL) … … 95 100 * as an extra reference. 96 101 * 97 * @param conn Connection102 * @param assoc Association 98 103 */ 99 104 static void udp_assoc_free(udp_assoc_t *assoc) … … 103 108 while (!list_empty(&assoc->rcv_queue)) { 104 109 link_t *link = list_first(&assoc->rcv_queue); 105 // ....; 110 udp_rcv_queue_entry_t *rqe = list_get_instance(link, 111 udp_rcv_queue_entry_t, link); 106 112 list_remove(link); 113 114 udp_msg_delete(rqe->msg); 115 free(rqe); 107 116 } 108 117 … … 219 228 int rc; 220 229 230 log_msg(LVL_DEBUG, "udp_assoc_send(%p, %p, %p)", 231 assoc, fsock, msg); 232 221 233 /* @a fsock can be used to override the foreign socket */ 222 234 sp = assoc->ident; … … 240 252 } 241 253 254 /** Get a received message. 255 * 256 * Pull one message from the association's receive queue. 257 */ 258 int udp_assoc_recv(udp_assoc_t *assoc, udp_msg_t **msg, udp_sock_t *fsock) 259 { 260 link_t *link; 261 udp_rcv_queue_entry_t *rqe; 262 263 log_msg(LVL_DEBUG, "udp_assoc_recv()"); 264 265 fibril_mutex_lock(&assoc->lock); 266 while (list_empty(&assoc->rcv_queue)) { 267 log_msg(LVL_DEBUG, "udp_assoc_recv() - waiting"); 268 fibril_condvar_wait(&assoc->rcv_queue_cv, &assoc->lock); 269 } 270 271 log_msg(LVL_DEBUG, "udp_assoc_recv() - got a message"); 272 link = list_first(&assoc->rcv_queue); 273 rqe = list_get_instance(link, udp_rcv_queue_entry_t, link); 274 list_remove(link); 275 fibril_mutex_unlock(&assoc->lock); 276 277 *msg = rqe->msg; 278 *fsock = rqe->sp.foreign; 279 280 return EOK; 281 } 282 283 /** Message received. 284 * 285 * Find the association to which the message belongs and queue it. 286 */ 287 void udp_assoc_received(udp_sockpair_t *rsp, udp_msg_t *msg) 288 { 289 udp_assoc_t *assoc; 290 int rc; 291 292 log_msg(LVL_DEBUG, "udp_assoc_received(%p, %p)", rsp, msg); 293 294 assoc = udp_assoc_find_ref(rsp); 295 if (assoc == NULL) { 296 log_msg(LVL_DEBUG, "No association found. Message dropped."); 297 /* XXX Generate ICMP error. */ 298 /* XXX Might propagate error directly by error return. */ 299 return; 300 } 301 302 rc = udp_assoc_queue_msg(assoc, rsp, msg); 303 if (rc != EOK) { 304 log_msg(LVL_DEBUG, "Out of memory. Message dropped."); 305 /* XXX Generate ICMP error? */ 306 } 307 } 308 309 static int udp_assoc_queue_msg(udp_assoc_t *assoc, udp_sockpair_t *sp, 310 udp_msg_t *msg) 311 { 312 udp_rcv_queue_entry_t *rqe; 313 314 log_msg(LVL_DEBUG, "udp_assoc_queue_msg(%p, %p, %p)", 315 assoc, sp, msg); 316 317 rqe = calloc(1, sizeof(udp_rcv_queue_entry_t)); 318 if (rqe == NULL) 319 return ENOMEM; 320 321 link_initialize(&rqe->link); 322 rqe->sp = *sp; 323 rqe->msg = msg; 324 325 fibril_mutex_lock(&assoc->lock); 326 list_append(&rqe->link, &assoc->rcv_queue); 327 fibril_mutex_unlock(&assoc->lock); 328 329 fibril_condvar_broadcast(&assoc->rcv_queue_cv); 330 331 return EOK; 332 } 333 334 /** Match socket with pattern. */ 335 static bool udp_socket_match(udp_sock_t *sock, udp_sock_t *patt) 336 { 337 log_msg(LVL_DEBUG, "udp_socket_match(sock=(%x,%u), pat=(%x,%u))", 338 sock->addr.ipv4, sock->port, patt->addr.ipv4, patt->port); 339 340 if (patt->addr.ipv4 != UDP_IPV4_ANY && 341 patt->addr.ipv4 != sock->addr.ipv4) 342 return false; 343 344 if (patt->port != UDP_PORT_ANY && 345 patt->port != sock->port) 346 return false; 347 348 log_msg(LVL_DEBUG, " -> match"); 349 350 return true; 351 } 352 353 /** Match socket pair with pattern. */ 354 static bool udp_sockpair_match(udp_sockpair_t *sp, udp_sockpair_t *pattern) 355 { 356 log_msg(LVL_DEBUG, "udp_sockpair_match(%p, %p)", sp, pattern); 357 358 if (!udp_socket_match(&sp->local, &pattern->local)) 359 return false; 360 361 if (!udp_socket_match(&sp->foreign, &pattern->foreign)) 362 return false; 363 364 log_msg(LVL_DEBUG, "Socket pair matched."); 365 return true; 366 } 367 368 369 /** Find association structure for specified socket pair. 370 * 371 * An association is uniquely identified by a socket pair. Look up our 372 * association map and return association structure based on socket pair. 373 * The association reference count is bumped by one. 374 * 375 * @param sp Socket pair 376 * @return Association structure or NULL if not found. 377 */ 378 static udp_assoc_t *udp_assoc_find_ref(udp_sockpair_t *sp) 379 { 380 log_msg(LVL_DEBUG, "udp_assoc_find_ref(%p)", sp); 381 382 fibril_mutex_lock(&assoc_list_lock); 383 384 list_foreach(assoc_list, link) { 385 udp_assoc_t *assoc = list_get_instance(link, udp_assoc_t, link); 386 udp_sockpair_t *asp = &assoc->ident; 387 log_msg(LVL_DEBUG, "compare with assoc (f:(%x,%u), l:(%x,%u))", 388 asp->foreign.addr.ipv4, asp->foreign.port, 389 asp->local.addr.ipv4, asp->local.port); 390 391 /* Skip unbound associations */ 392 if (asp->local.port == UDP_PORT_ANY) 393 continue; 394 395 if (udp_sockpair_match(sp, asp)) { 396 log_msg(LVL_DEBUG, "Returning assoc %p", assoc); 397 udp_assoc_addref(assoc); 398 fibril_mutex_unlock(&assoc_list_lock); 399 return assoc; 400 } 401 } 402 403 fibril_mutex_unlock(&assoc_list_lock); 404 return NULL; 405 } 406 407 242 408 /** 243 409 * @}
Note:
See TracChangeset
for help on using the changeset viewer.