source: mainline/uspace/lib/nettl/src/amap.c@ 6969eea3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6969eea3 was e1b4ae0, checked in by Jiri Svoboda <jiri@…>, 8 years ago

Start adding tests for TCP conn module. Make sure all connections have been freed at the end of a test.

  • Property mode set to 100644
File size: 18.8 KB
RevLine 
[2989c7e]1/*
2 * Copyright (c) 2015 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libnettl
30 * @{
31 */
32
33/**
34 * @file Association map
35 *
36 * Manages allocations of endpoints / endpoint pairs (corresponding to
37 * UDP associations, TCP listeners and TCP connections)
[b10460a]38 *
39 * An association map contains different types of entries, based on which
40 * set of attributes (key) they specify. In order from most specific to the
41 * least specific one:
42 *
43 * - repla (remote endpoint, local address)
44 * - laddr (local address)
45 * - llink (local link)
46 * - unspec (unspecified)
47 *
48 * In the unspecified case only the local port is known and the entry matches
49 * all remote and local addresses.
[2989c7e]50 */
51
[ab6326bc]52#include <adt/list.h>
[2989c7e]53#include <errno.h>
[ab6326bc]54#include <inet/addr.h>
[2989c7e]55#include <inet/inet.h>
56#include <io/log.h>
57#include <nettl/amap.h>
58#include <stdint.h>
59#include <stdlib.h>
60
[b10460a]61/** Create association map.
62 *
63 * @param rmap Place to store pointer to new association map
64 * @return EOk on success, ENOMEM if out of memory
65 */
[2989c7e]66int amap_create(amap_t **rmap)
67{
68 amap_t *map;
[ab6326bc]69 int rc;
70
[c3f7d37]71 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_create()");
[2989c7e]72
73 map = calloc(1, sizeof(amap_t));
74 if (map == NULL)
75 return ENOMEM;
76
[ab6326bc]77 rc = portrng_create(&map->unspec);
78 if (rc != EOK) {
79 assert(rc == ENOMEM);
80 free(map);
81 return ENOMEM;
82 }
83
84 list_initialize(&map->repla);
85 list_initialize(&map->laddr);
86 list_initialize(&map->llink);
87
88 *rmap = map;
[2989c7e]89 return EOK;
90}
91
[b10460a]92/** Destroy association map.
93 *
94 * @param map Association map
95 */
[2989c7e]96void amap_destroy(amap_t *map)
97{
[c3f7d37]98 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_destroy()");
[e1b4ae0]99
100 assert(list_empty(&map->repla));
101 assert(list_empty(&map->laddr));
102 assert(list_empty(&map->llink));
[2989c7e]103 free(map);
104}
105
[b10460a]106/** Find exact repla.
107 *
108 * Find repla (remote endpoint, local address) entry by exact match.
109 *
110 * @param map Association map
111 * @param rep Remote endpoint
112 * @param la Local address
113 * @param rrepla Place to store pointer to repla
114 *
115 * @return EOK on success, ENOENT if not found
116 */
[ab6326bc]117static int amap_repla_find(amap_t *map, inet_ep_t *rep, inet_addr_t *la,
118 amap_repla_t **rrepla)
119{
120 char *sraddr, *sladdr;
121
122 (void) inet_addr_format(&rep->addr, &sraddr);
123 (void) inet_addr_format(la, &sladdr);
124
[c3f7d37]125 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_repla_find(): rep=(%s,%" PRIu16
[ab6326bc]126 ") la=%s", sraddr, rep->port, sladdr);
127 free(sraddr);
128 free(sladdr);
129
130 list_foreach(map->repla, lamap, amap_repla_t, repla) {
131 (void) inet_addr_format(&repla->rep.addr, &sraddr);
132 (void) inet_addr_format(&repla->laddr, &sladdr);
[c3f7d37]133 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_repla_find(): "
[ab6326bc]134 "compare to rep=(%s, %" PRIu16 ") la=%s",
135 sraddr, repla->rep.port, sladdr);
136 free(sraddr);
137 free(sladdr);
138 if (inet_addr_compare(&repla->rep.addr, &rep->addr) &&
139 repla->rep.port == rep->port &&
140 inet_addr_compare(&repla->laddr, la)) {
141 *rrepla = repla;
142 return EOK;
143 }
144 }
145
146 *rrepla = NULL;
147 return ENOENT;
148}
149
[b10460a]150/** Insert repla.
151 *
152 * Insert new repla (remote endpoint, local address) entry to association map.
153 *
154 * @param amap Association map
155 * @param rep Remote endpoint
156 * @param la Local address
157 * @param rrepla Place to store pointer to new repla
158 *
159 * @return EOK on success, ENOMEM if out of memory
160 */
[ab6326bc]161static int amap_repla_insert(amap_t *map, inet_ep_t *rep, inet_addr_t *la,
162 amap_repla_t **rrepla)
163{
164 amap_repla_t *repla;
165 int rc;
166
167 repla = calloc(1, sizeof(amap_repla_t));
168 if (repla == NULL) {
169 *rrepla = NULL;
170 return ENOMEM;
171 }
172
173 rc = portrng_create(&repla->portrng);
174 if (rc != EOK) {
175 free(repla);
176 return ENOMEM;
177 }
178
179 repla->rep = *rep;
180 repla->laddr = *la;
181 list_append(&repla->lamap, &map->repla);
182
183 *rrepla = repla;
184 return EOK;
185}
186
[b10460a]187/** Remove repla from association map.
188 *
189 * Remove repla (remote endpoint, local address) from association map.
190 *
191 * @param map Association map
192 * @param repla Repla
193 */
[ab6326bc]194static void amap_repla_remove(amap_t *map, amap_repla_t *repla)
195{
196 list_remove(&repla->lamap);
197 portrng_destroy(repla->portrng);
198 free(repla);
199}
200
[b10460a]201/** Find exact laddr.
202 *
203 * Find laddr (local address) entry by exact match.
204 *
205 * @param map Association map
206 * @param addr Address
207 * @param rladdr Place to store pointer to laddr entry
208 *
209 * @return EOK on success, ENOENT if not found.
210 */
[ab6326bc]211static int amap_laddr_find(amap_t *map, inet_addr_t *addr,
212 amap_laddr_t **rladdr)
213{
214 list_foreach(map->laddr, lamap, amap_laddr_t, laddr) {
215 if (inet_addr_compare(&laddr->laddr, addr)) {
216 *rladdr = laddr;
217 return EOK;
218 }
219 }
220
221 *rladdr = NULL;
222 return ENOENT;
223}
224
[b10460a]225/** Insert laddr.
226 *
227 * Insert new laddr (local address) entry to association map.
228 *
229 * @param addr Local address
230 * @param rladdr Place to store pointer to new laddr
231 *
232 * @return EOK on success, ENOMEM if out of memory
233 */
[ab6326bc]234static int amap_laddr_insert(amap_t *map, inet_addr_t *addr,
235 amap_laddr_t **rladdr)
236{
237 amap_laddr_t *laddr;
238 int rc;
239
240 laddr = calloc(1, sizeof(amap_laddr_t));
241 if (laddr == NULL) {
242 *rladdr = NULL;
243 return ENOMEM;
244 }
245
246 rc = portrng_create(&laddr->portrng);
247 if (rc != EOK) {
248 free(laddr);
249 return ENOMEM;
250 }
251
252 laddr->laddr = *addr;
253 list_append(&laddr->lamap, &map->laddr);
254
255 *rladdr = laddr;
256 return EOK;
257}
258
[b10460a]259/** Remove laddr from association map.
260 *
261 * Remove laddr (local address) entry from association map.
262 *
263 * @param map Association map
264 * @param laddr Laddr entry
265 */
[ab6326bc]266static void amap_laddr_remove(amap_t *map, amap_laddr_t *laddr)
267{
268 list_remove(&laddr->lamap);
269 portrng_destroy(laddr->portrng);
270 free(laddr);
271}
272
[b10460a]273/** Find exact llink.
274 *
275 * Find llink (local link) entry by exact match.
276 *
277 * @param map Association map
278 * @param link_id Local link ID
279 * @param rllink Place to store pointer to llink entry
280 *
281 * @return EOK on success, ENOENT if not found.
282 */
[ab6326bc]283static int amap_llink_find(amap_t *map, sysarg_t link_id,
284 amap_llink_t **rllink)
285{
286 list_foreach(map->llink, lamap, amap_llink_t, llink) {
287 if (llink->llink == link_id) {
288 *rllink = llink;
289 return EOK;
290 }
291 }
292
293 *rllink = NULL;
294 return ENOENT;
295}
296
[b10460a]297/** Insert llink.
298 *
299 * Insert new llink (local link) entry to association map.
300 *
301 * @param link_id Local link
302 * @param rllink Place to store pointer to new llink
303 *
304 * @return EOK on success, ENOMEM if out of memory
305 */
[ab6326bc]306static int amap_llink_insert(amap_t *map, sysarg_t link_id,
307 amap_llink_t **rllink)
308{
309 amap_llink_t *llink;
310 int rc;
311
312 llink = calloc(1, sizeof(amap_llink_t));
313 if (llink == NULL) {
314 *rllink = NULL;
315 return ENOMEM;
316 }
317
318 rc = portrng_create(&llink->portrng);
319 if (rc != EOK) {
320 free(llink);
321 return ENOMEM;
322 }
323
324 llink->llink = link_id;
325 list_append(&llink->lamap, &map->llink);
326
327 *rllink = llink;
328 return EOK;
329}
330
[b10460a]331/** Remove llink from association map.
332 *
333 * Remove llink (local link) entry from association map.
334 *
335 * @param map Association map
336 * @param llink Llink entry
337 */
[ab6326bc]338static void amap_llink_remove(amap_t *map, amap_llink_t *llink)
339{
340 list_remove(&llink->lamap);
341 portrng_destroy(llink->portrng);
342 free(llink);
343}
344
[b10460a]345/** Insert endpoint pair into map with repla as key.
346 *
347 * If local port number is not specified, it is allocated.
348 *
349 * @param map Association map
350 * @param epp Endpoint pair, possibly with local port inet_port_any
351 * @param arg arg User value
352 * @param flags Flags
353 * @param aepp Place to store actual endpoint pair, possibly with allocated port
354 *
[8a637a4]355 * @return EOK on success, EEXIST if conflicting epp exists,
[b10460a]356 * ENOMEM if out of memory
357 */
[ab6326bc]358static int amap_insert_repla(amap_t *map, inet_ep2_t *epp, void *arg,
359 amap_flags_t flags, inet_ep2_t *aepp)
360{
361 amap_repla_t *repla;
362 inet_ep2_t mepp;
363 int rc;
364
[c3f7d37]365 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_repla()");
[ab6326bc]366
367 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
368 if (rc != EOK) {
369 /* New repla */
370 rc = amap_repla_insert(map, &epp->remote, &epp->local.addr,
371 &repla);
372 if (rc != EOK) {
373 assert(rc == ENOMEM);
374 return rc;
375 }
376 }
377
378 mepp = *epp;
379
380 rc = portrng_alloc(repla->portrng, epp->local.port, arg, flags,
381 &mepp.local.port);
382 if (rc != EOK) {
383 return rc;
384 }
385
386 *aepp = mepp;
387 return EOK;
388}
389
[b10460a]390/** Insert endpoint pair into map with laddr as key.
391 *
392 * If local port number is not specified, it is allocated.
393 *
394 * @param map Association map
395 * @param epp Endpoint pair, possibly with local port inet_port_any
396 * @param arg arg User value
397 * @param flags Flags
398 * @param aepp Place to store actual endpoint pair, possibly with allocated port
399 *
[8a637a4]400 * @return EOK on success, EEXIST if conflicting epp exists,
[b10460a]401 * ENOMEM if out of memory
402 */
[ab6326bc]403static int amap_insert_laddr(amap_t *map, inet_ep2_t *epp, void *arg,
404 amap_flags_t flags, inet_ep2_t *aepp)
405{
406 amap_laddr_t *laddr;
407 inet_ep2_t mepp;
408 int rc;
409
[c3f7d37]410 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_laddr()");
[ab6326bc]411
412 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
413 if (rc != EOK) {
414 /* New laddr */
415 rc = amap_laddr_insert(map, &epp->local.addr, &laddr);
416 if (rc != EOK) {
417 assert(rc == ENOMEM);
418 return rc;
419 }
420 }
421
422 mepp = *epp;
423
424 rc = portrng_alloc(laddr->portrng, epp->local.port, arg, flags,
425 &mepp.local.port);
426 if (rc != EOK) {
427 return rc;
428 }
429
430 *aepp = mepp;
431 return EOK;
432}
433
[b10460a]434/** Insert endpoint pair into map with llink as key.
435 *
436 * If local port number is not specified, it is allocated.
437 *
438 * @param map Association map
439 * @param epp Endpoint pair, possibly with local port inet_port_any
440 * @param arg arg User value
441 * @param flags Flags
442 * @param aepp Place to store actual endpoint pair, possibly with allocated port
443 *
[8a637a4]444 * @return EOK on success, EEXIST if conflicting epp exists,
[b10460a]445 * ENOMEM if out of memory
446 */
[ab6326bc]447static int amap_insert_llink(amap_t *map, inet_ep2_t *epp, void *arg,
448 amap_flags_t flags, inet_ep2_t *aepp)
449{
450 amap_llink_t *llink;
451 inet_ep2_t mepp;
452 int rc;
453
[c3f7d37]454 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_llink()");
[ab6326bc]455
456 rc = amap_llink_find(map, epp->local_link, &llink);
457 if (rc != EOK) {
458 /* New llink */
459 rc = amap_llink_insert(map, epp->local_link, &llink);
460 if (rc != EOK) {
461 assert(rc == ENOMEM);
462 return rc;
463 }
464 }
465
466 mepp = *epp;
467
468 rc = portrng_alloc(llink->portrng, epp->local.port, arg, flags,
469 &mepp.local.port);
470 if (rc != EOK) {
471 return rc;
472 }
473
474 *aepp = mepp;
475 return EOK;
476}
477
[b10460a]478/** Insert endpoint pair into map with unspec as key.
479 *
480 * If local port number is not specified, it is allocated.
481 *
482 * @param map Association map
483 * @param epp Endpoint pair, possibly with local port inet_port_any
484 * @param arg arg User value
485 * @param flags Flags
486 * @param aepp Place to store actual endpoint pair, possibly with allocated port
487 *
[8a637a4]488 * @return EOK on success, EEXIST if conflicting epp exists,
[b10460a]489 * ENOMEM if out of memory
490 */
[ab6326bc]491static int amap_insert_unspec(amap_t *map, inet_ep2_t *epp, void *arg,
492 amap_flags_t flags, inet_ep2_t *aepp)
493{
494 inet_ep2_t mepp;
495 int rc;
496
[c3f7d37]497 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_unspec()");
[ab6326bc]498 mepp = *epp;
499
500 rc = portrng_alloc(map->unspec, epp->local.port, arg, flags,
501 &mepp.local.port);
502 if (rc != EOK) {
503 return rc;
504 }
505
506 *aepp = mepp;
507 return EOK;
508}
509
[2989c7e]510/** Insert endpoint pair into map.
511 *
512 * If local endpoint is not fully specified, it is filled in (determine
513 * source address, allocate port number). Checks for conflicting endpoint pair.
514 *
515 * @param map Association map
516 * @param epp Endpoint pair, possibly with local port inet_port_any
517 * @param arg arg User value
518 * @param flags Flags
519 * @param aepp Place to store actual endpoint pair, possibly with allocated port
520 *
[8a637a4]521 * @return EOK on success, EEXIST if conflicting epp exists,
[2989c7e]522 * ENOMEM if out of memory
523 */
524int amap_insert(amap_t *map, inet_ep2_t *epp, void *arg, amap_flags_t flags,
525 inet_ep2_t *aepp)
526{
[ab6326bc]527 bool raddr, rport, laddr, llink;
528 inet_ep2_t mepp;
[2989c7e]529 int rc;
530
[c3f7d37]531 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert()");
[2989c7e]532
[ab6326bc]533 mepp = *epp;
[2989c7e]534
535 /* Fill in local address? */
536 if (!inet_addr_is_any(&epp->remote.addr) &&
537 inet_addr_is_any(&epp->local.addr)) {
[c3f7d37]538 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
[2989c7e]539 "determine local address");
[ab6326bc]540 rc = inet_get_srcaddr(&epp->remote.addr, 0, &mepp.local.addr);
[2989c7e]541 if (rc != EOK) {
[c3f7d37]542 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
[2989c7e]543 "cannot determine local address");
544 return rc;
545 }
546 } else {
[c3f7d37]547 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
[2989c7e]548 "local address specified or remote address not specified");
549 }
550
[ab6326bc]551 raddr = !inet_addr_is_any(&mepp.remote.addr);
552 rport = mepp.remote.port != inet_port_any;
553 laddr = !inet_addr_is_any(&mepp.local.addr);
554 llink = mepp.local_link != 0;
555
556 if (raddr && rport && laddr && !llink) {
557 return amap_insert_repla(map, &mepp, arg, flags, aepp);
558 } else if (!raddr && !rport && laddr && !llink) {
559 return amap_insert_laddr(map, &mepp, arg, flags, aepp);
560 } else if (!raddr && !rport && !laddr && llink) {
561 return amap_insert_llink(map, &mepp, arg, flags, aepp);
562 } else if (!raddr && !rport && !laddr && !llink) {
563 return amap_insert_unspec(map, &mepp, arg, flags, aepp);
564 } else {
[c3f7d37]565 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: invalid "
[ab6326bc]566 "combination of raddr=%d rport=%d laddr=%d llink=%d",
567 raddr, rport, laddr, llink);
568 return EINVAL;
[2989c7e]569 }
570
571 return EOK;
572}
573
[b10460a]574/** Remove endpoint pair using repla as key from map.
575 *
576 * The endpoint pair must be present in the map, otherwise behavior
577 * is unspecified.
578 *
579 * @param map Association map
580 * @param epp Endpoint pair
581 */
[ab6326bc]582static void amap_remove_repla(amap_t *map, inet_ep2_t *epp)
583{
584 amap_repla_t *repla;
585 int rc;
586
587 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
588 if (rc != EOK) {
[c3f7d37]589 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_repla: not found");
[ab6326bc]590 return;
591 }
592
593 portrng_free_port(repla->portrng, epp->local.port);
594
595 if (portrng_empty(repla->portrng))
596 amap_repla_remove(map, repla);
597}
598
[b10460a]599/** Remove endpoint pair using laddr as key from map.
600 *
601 * The endpoint pair must be present in the map, otherwise behavior
602 * is unspecified.
603 *
604 * @param map Association map
605 * @param epp Endpoint pair
606 */
[ab6326bc]607static void amap_remove_laddr(amap_t *map, inet_ep2_t *epp)
608{
609 amap_laddr_t *laddr;
610 int rc;
611
612 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
613 if (rc != EOK) {
[c3f7d37]614 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_laddr: not found");
[ab6326bc]615 return;
616 }
617
618 portrng_free_port(laddr->portrng, epp->local.port);
619
620 if (portrng_empty(laddr->portrng))
621 amap_laddr_remove(map, laddr);
622}
623
[b10460a]624/** Remove endpoint pair using llink as key from map.
625 *
626 * The endpoint pair must be present in the map, otherwise behavior
627 * is unspecified.
628 *
629 * @param map Association map
630 * @param epp Endpoint pair
631 */
[ab6326bc]632static void amap_remove_llink(amap_t *map, inet_ep2_t *epp)
633{
634 amap_llink_t *llink;
635 int rc;
636
637 rc = amap_llink_find(map, epp->local_link, &llink);
638 if (rc != EOK) {
[c3f7d37]639 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_llink: not found");
[ab6326bc]640 return;
641 }
642
643 portrng_free_port(llink->portrng, epp->local.port);
644
645 if (portrng_empty(llink->portrng))
646 amap_llink_remove(map, llink);
647}
648
[b10460a]649/** Remove endpoint pair using unspec as key from map.
650 *
651 * The endpoint pair must be present in the map, otherwise behavior
652 * is unspecified.
653 *
654 * @param map Association map
655 * @param epp Endpoint pair
656 */
[ab6326bc]657static void amap_remove_unspec(amap_t *map, inet_ep2_t *epp)
658{
659 portrng_free_port(map->unspec, epp->local.port);
660}
661
[b10460a]662/** Remove endpoint pair from map.
663 *
664 * The endpoint pair must be present in the map, otherwise behavior
665 * is unspecified.
666 *
667 * @param map Association map
668 * @param epp Endpoint pair
669 */
[2989c7e]670void amap_remove(amap_t *map, inet_ep2_t *epp)
671{
[ab6326bc]672 bool raddr, rport, laddr, llink;
673
[c3f7d37]674 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove()");
[ab6326bc]675
676 raddr = !inet_addr_is_any(&epp->remote.addr);
677 rport = epp->remote.port != inet_port_any;
678 laddr = !inet_addr_is_any(&epp->local.addr);
679 llink = epp->local_link != 0;
680
681 if (raddr && rport && laddr && !llink) {
682 amap_remove_repla(map, epp);
683 } else if (!raddr && !rport && laddr && !llink) {
684 amap_remove_laddr(map, epp);
685 } else if (!raddr && !rport && !laddr && llink) {
686 amap_remove_llink(map, epp);
687 } else if (!raddr && !rport && !laddr && !llink) {
688 amap_remove_unspec(map, epp);
689 } else {
[c3f7d37]690 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove: invalid "
[ab6326bc]691 "combination of raddr=%d rport=%d laddr=%d llink=%d",
692 raddr, rport, laddr, llink);
693 return;
694 }
[2989c7e]695}
696
[8d48c7e]697/** Find association matching an endpoint pair.
698 *
699 * Used to find which association to deliver a datagram to.
700 *
701 * @param map Association map
702 * @param epp Endpoint pair
703 * @param rarg Place to store user argument for the matching association.
704 *
705 * @return EOK on success, ENOENT if not found.
706 */
707int amap_find_match(amap_t *map, inet_ep2_t *epp, void **rarg)
[2989c7e]708{
[8d48c7e]709 int rc;
710 amap_repla_t *repla;
711 amap_laddr_t *laddr;
712 amap_llink_t *llink;
713
[c3f7d37]714 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_find_match(llink=%zu)",
[8d48c7e]715 epp->local_link);
716
717 /* Remode endpoint, local address */
718 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
719 if (rc == EOK) {
720 rc = portrng_find_port(repla->portrng, epp->local.port,
721 rarg);
722 if (rc == EOK) {
[c3f7d37]723 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched repla / "
[8d48c7e]724 "port %" PRIu16, epp->local.port);
725 return EOK;
726 }
727 }
728
729 /* Local address */
730 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
731 if (rc == EOK) {
732 rc = portrng_find_port(laddr->portrng, epp->local.port,
733 rarg);
734 if (rc == EOK) {
[c3f7d37]735 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched laddr / "
[8d48c7e]736 "port %" PRIu16, epp->local.port);
737 return EOK;
738 }
739 }
740
741 /* Local link */
742 rc = amap_llink_find(map, epp->local_link, &llink);
743 if (epp->local_link != 0 && rc == EOK) {
744 rc = portrng_find_port(llink->portrng, epp->local.port,
745 rarg);
746 if (rc == EOK) {
[c3f7d37]747 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched llink / "
[8d48c7e]748 "port %" PRIu16, epp->local.port);
749 return EOK;
750 }
751 }
752
753 /* Unspecified */
754 rc = portrng_find_port(map->unspec, epp->local.port, rarg);
755 if (rc == EOK) {
[c3f7d37]756 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched unspec / port %" PRIu16,
[8d48c7e]757 epp->local.port);
758 return EOK;
759 }
760
[c3f7d37]761 log_msg(LOG_DEFAULT, LVL_DEBUG2, "No match.");
[8d48c7e]762 return ENOENT;
[2989c7e]763}
764
765/**
766 * @}
767 */
Note: See TracBrowser for help on using the repository browser.