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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since de9992c was b7fd2a0, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Use errno_t in all uspace and kernel code.

Change type of every variable, parameter and return value that holds an
<errno.h> constant to either errno_t (the usual case), or sys_errno_t
(some places in kernel). This is for the purpose of self-documentation,
as well as for type-checking with a bit of type definition hackery.

Although this is a massive commit, it is a simple text replacement, and thus
is very easy to verify. Simply do the following:

`
git checkout <this commit's hash>
git reset HEAD
git add .
tools/srepl '\berrno_t\b' int
git add .
tools/srepl '\bsys_errno_t\b' sysarg_t
git reset
git diff
`

While this doesn't ensure that the replacements are correct, it does ensure
that the commit doesn't do anything except those replacements. Since errno_t
is typedef'd to int in the usual case (and sys_errno_t to sysarg_t), even if
incorrect, this commit cannot change behavior.

  • Property mode set to 100644
File size: 19.3 KB
Line 
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)
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.
50 */
51
52#include <adt/list.h>
53#include <errno.h>
54#include <inet/addr.h>
55#include <inet/inet.h>
56#include <io/log.h>
57#include <nettl/amap.h>
58#include <stdint.h>
59#include <stdlib.h>
60
61/** Convert association map flags to port range flags.
62 *
63 * @param flags Association map flags
64 * @return Port range flags
65 */
66static portrng_flags_t aflags_to_pflags(amap_flags_t flags)
67{
68 portrng_flags_t pflags;
69
70 pflags = 0;
71 if ((flags & af_allow_system) != 0)
72 pflags |= pf_allow_system;
73
74 return pflags;
75}
76
77/** Create association map.
78 *
79 * @param rmap Place to store pointer to new association map
80 * @return EOk on success, ENOMEM if out of memory
81 */
82errno_t amap_create(amap_t **rmap)
83{
84 amap_t *map;
85 errno_t rc;
86
87 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_create()");
88
89 map = calloc(1, sizeof(amap_t));
90 if (map == NULL)
91 return ENOMEM;
92
93 rc = portrng_create(&map->unspec);
94 if (rc != EOK) {
95 assert(rc == ENOMEM);
96 free(map);
97 return ENOMEM;
98 }
99
100 list_initialize(&map->repla);
101 list_initialize(&map->laddr);
102 list_initialize(&map->llink);
103
104 *rmap = map;
105 return EOK;
106}
107
108/** Destroy association map.
109 *
110 * @param map Association map
111 */
112void amap_destroy(amap_t *map)
113{
114 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_destroy()");
115
116 assert(list_empty(&map->repla));
117 assert(list_empty(&map->laddr));
118 assert(list_empty(&map->llink));
119 free(map);
120}
121
122/** Find exact repla.
123 *
124 * Find repla (remote endpoint, local address) entry by exact match.
125 *
126 * @param map Association map
127 * @param rep Remote endpoint
128 * @param la Local address
129 * @param rrepla Place to store pointer to repla
130 *
131 * @return EOK on success, ENOENT if not found
132 */
133static errno_t amap_repla_find(amap_t *map, inet_ep_t *rep, inet_addr_t *la,
134 amap_repla_t **rrepla)
135{
136 char *sraddr, *sladdr;
137
138 (void) inet_addr_format(&rep->addr, &sraddr);
139 (void) inet_addr_format(la, &sladdr);
140
141 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_repla_find(): rep=(%s,%" PRIu16
142 ") la=%s", sraddr, rep->port, sladdr);
143 free(sraddr);
144 free(sladdr);
145
146 list_foreach(map->repla, lamap, amap_repla_t, repla) {
147 (void) inet_addr_format(&repla->rep.addr, &sraddr);
148 (void) inet_addr_format(&repla->laddr, &sladdr);
149 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_repla_find(): "
150 "compare to rep=(%s, %" PRIu16 ") la=%s",
151 sraddr, repla->rep.port, sladdr);
152 free(sraddr);
153 free(sladdr);
154 if (inet_addr_compare(&repla->rep.addr, &rep->addr) &&
155 repla->rep.port == rep->port &&
156 inet_addr_compare(&repla->laddr, la)) {
157 *rrepla = repla;
158 return EOK;
159 }
160 }
161
162 *rrepla = NULL;
163 return ENOENT;
164}
165
166/** Insert repla.
167 *
168 * Insert new repla (remote endpoint, local address) entry to association map.
169 *
170 * @param amap Association map
171 * @param rep Remote endpoint
172 * @param la Local address
173 * @param rrepla Place to store pointer to new repla
174 *
175 * @return EOK on success, ENOMEM if out of memory
176 */
177static errno_t amap_repla_insert(amap_t *map, inet_ep_t *rep, inet_addr_t *la,
178 amap_repla_t **rrepla)
179{
180 amap_repla_t *repla;
181 errno_t rc;
182
183 repla = calloc(1, sizeof(amap_repla_t));
184 if (repla == NULL) {
185 *rrepla = NULL;
186 return ENOMEM;
187 }
188
189 rc = portrng_create(&repla->portrng);
190 if (rc != EOK) {
191 free(repla);
192 return ENOMEM;
193 }
194
195 repla->rep = *rep;
196 repla->laddr = *la;
197 list_append(&repla->lamap, &map->repla);
198
199 *rrepla = repla;
200 return EOK;
201}
202
203/** Remove repla from association map.
204 *
205 * Remove repla (remote endpoint, local address) from association map.
206 *
207 * @param map Association map
208 * @param repla Repla
209 */
210static void amap_repla_remove(amap_t *map, amap_repla_t *repla)
211{
212 list_remove(&repla->lamap);
213 portrng_destroy(repla->portrng);
214 free(repla);
215}
216
217/** Find exact laddr.
218 *
219 * Find laddr (local address) entry by exact match.
220 *
221 * @param map Association map
222 * @param addr Address
223 * @param rladdr Place to store pointer to laddr entry
224 *
225 * @return EOK on success, ENOENT if not found.
226 */
227static errno_t amap_laddr_find(amap_t *map, inet_addr_t *addr,
228 amap_laddr_t **rladdr)
229{
230 list_foreach(map->laddr, lamap, amap_laddr_t, laddr) {
231 if (inet_addr_compare(&laddr->laddr, addr)) {
232 *rladdr = laddr;
233 return EOK;
234 }
235 }
236
237 *rladdr = NULL;
238 return ENOENT;
239}
240
241/** Insert laddr.
242 *
243 * Insert new laddr (local address) entry to association map.
244 *
245 * @param addr Local address
246 * @param rladdr Place to store pointer to new laddr
247 *
248 * @return EOK on success, ENOMEM if out of memory
249 */
250static errno_t amap_laddr_insert(amap_t *map, inet_addr_t *addr,
251 amap_laddr_t **rladdr)
252{
253 amap_laddr_t *laddr;
254 errno_t rc;
255
256 laddr = calloc(1, sizeof(amap_laddr_t));
257 if (laddr == NULL) {
258 *rladdr = NULL;
259 return ENOMEM;
260 }
261
262 rc = portrng_create(&laddr->portrng);
263 if (rc != EOK) {
264 free(laddr);
265 return ENOMEM;
266 }
267
268 laddr->laddr = *addr;
269 list_append(&laddr->lamap, &map->laddr);
270
271 *rladdr = laddr;
272 return EOK;
273}
274
275/** Remove laddr from association map.
276 *
277 * Remove laddr (local address) entry from association map.
278 *
279 * @param map Association map
280 * @param laddr Laddr entry
281 */
282static void amap_laddr_remove(amap_t *map, amap_laddr_t *laddr)
283{
284 list_remove(&laddr->lamap);
285 portrng_destroy(laddr->portrng);
286 free(laddr);
287}
288
289/** Find exact llink.
290 *
291 * Find llink (local link) entry by exact match.
292 *
293 * @param map Association map
294 * @param link_id Local link ID
295 * @param rllink Place to store pointer to llink entry
296 *
297 * @return EOK on success, ENOENT if not found.
298 */
299static errno_t amap_llink_find(amap_t *map, sysarg_t link_id,
300 amap_llink_t **rllink)
301{
302 list_foreach(map->llink, lamap, amap_llink_t, llink) {
303 if (llink->llink == link_id) {
304 *rllink = llink;
305 return EOK;
306 }
307 }
308
309 *rllink = NULL;
310 return ENOENT;
311}
312
313/** Insert llink.
314 *
315 * Insert new llink (local link) entry to association map.
316 *
317 * @param link_id Local link
318 * @param rllink Place to store pointer to new llink
319 *
320 * @return EOK on success, ENOMEM if out of memory
321 */
322static errno_t amap_llink_insert(amap_t *map, sysarg_t link_id,
323 amap_llink_t **rllink)
324{
325 amap_llink_t *llink;
326 errno_t rc;
327
328 llink = calloc(1, sizeof(amap_llink_t));
329 if (llink == NULL) {
330 *rllink = NULL;
331 return ENOMEM;
332 }
333
334 rc = portrng_create(&llink->portrng);
335 if (rc != EOK) {
336 free(llink);
337 return ENOMEM;
338 }
339
340 llink->llink = link_id;
341 list_append(&llink->lamap, &map->llink);
342
343 *rllink = llink;
344 return EOK;
345}
346
347/** Remove llink from association map.
348 *
349 * Remove llink (local link) entry from association map.
350 *
351 * @param map Association map
352 * @param llink Llink entry
353 */
354static void amap_llink_remove(amap_t *map, amap_llink_t *llink)
355{
356 list_remove(&llink->lamap);
357 portrng_destroy(llink->portrng);
358 free(llink);
359}
360
361/** Insert endpoint pair into map with repla as key.
362 *
363 * If local port number is not specified, it is allocated.
364 *
365 * @param map Association map
366 * @param epp Endpoint pair, possibly with local port inet_port_any
367 * @param arg arg User value
368 * @param flags Flags
369 * @param aepp Place to store actual endpoint pair, possibly with allocated port
370 *
371 * @return EOK on success, EEXIST if conflicting epp exists,
372 * ENOMEM if out of memory
373 */
374static errno_t amap_insert_repla(amap_t *map, inet_ep2_t *epp, void *arg,
375 amap_flags_t flags, inet_ep2_t *aepp)
376{
377 amap_repla_t *repla;
378 inet_ep2_t mepp;
379 errno_t rc;
380
381 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_repla()");
382
383 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
384 if (rc != EOK) {
385 /* New repla */
386 rc = amap_repla_insert(map, &epp->remote, &epp->local.addr,
387 &repla);
388 if (rc != EOK) {
389 assert(rc == ENOMEM);
390 return rc;
391 }
392 }
393
394 mepp = *epp;
395
396 rc = portrng_alloc(repla->portrng, epp->local.port, arg, aflags_to_pflags(flags),
397 &mepp.local.port);
398 if (rc != EOK) {
399 return rc;
400 }
401
402 *aepp = mepp;
403 return EOK;
404}
405
406/** Insert endpoint pair into map with laddr as key.
407 *
408 * If local port number is not specified, it is allocated.
409 *
410 * @param map Association map
411 * @param epp Endpoint pair, possibly with local port inet_port_any
412 * @param arg arg User value
413 * @param flags Flags
414 * @param aepp Place to store actual endpoint pair, possibly with allocated port
415 *
416 * @return EOK on success, EEXIST if conflicting epp exists,
417 * ENOMEM if out of memory
418 */
419static errno_t amap_insert_laddr(amap_t *map, inet_ep2_t *epp, void *arg,
420 amap_flags_t flags, inet_ep2_t *aepp)
421{
422 amap_laddr_t *laddr;
423 inet_ep2_t mepp;
424 errno_t rc;
425
426 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_laddr()");
427
428 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
429 if (rc != EOK) {
430 /* New laddr */
431 rc = amap_laddr_insert(map, &epp->local.addr, &laddr);
432 if (rc != EOK) {
433 assert(rc == ENOMEM);
434 return rc;
435 }
436 }
437
438 mepp = *epp;
439
440 rc = portrng_alloc(laddr->portrng, epp->local.port, arg, aflags_to_pflags(flags),
441 &mepp.local.port);
442 if (rc != EOK) {
443 return rc;
444 }
445
446 *aepp = mepp;
447 return EOK;
448}
449
450/** Insert endpoint pair into map with llink as key.
451 *
452 * If local port number is not specified, it is allocated.
453 *
454 * @param map Association map
455 * @param epp Endpoint pair, possibly with local port inet_port_any
456 * @param arg arg User value
457 * @param flags Flags
458 * @param aepp Place to store actual endpoint pair, possibly with allocated port
459 *
460 * @return EOK on success, EEXIST if conflicting epp exists,
461 * ENOMEM if out of memory
462 */
463static errno_t amap_insert_llink(amap_t *map, inet_ep2_t *epp, void *arg,
464 amap_flags_t flags, inet_ep2_t *aepp)
465{
466 amap_llink_t *llink;
467 inet_ep2_t mepp;
468 errno_t rc;
469
470 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_llink()");
471
472 rc = amap_llink_find(map, epp->local_link, &llink);
473 if (rc != EOK) {
474 /* New llink */
475 rc = amap_llink_insert(map, epp->local_link, &llink);
476 if (rc != EOK) {
477 assert(rc == ENOMEM);
478 return rc;
479 }
480 }
481
482 mepp = *epp;
483
484 rc = portrng_alloc(llink->portrng, epp->local.port, arg, aflags_to_pflags(flags),
485 &mepp.local.port);
486 if (rc != EOK) {
487 return rc;
488 }
489
490 *aepp = mepp;
491 return EOK;
492}
493
494/** Insert endpoint pair into map with unspec as key.
495 *
496 * If local port number is not specified, it is allocated.
497 *
498 * @param map Association map
499 * @param epp Endpoint pair, possibly with local port inet_port_any
500 * @param arg arg User value
501 * @param flags Flags
502 * @param aepp Place to store actual endpoint pair, possibly with allocated port
503 *
504 * @return EOK on success, EEXIST if conflicting epp exists,
505 * ENOMEM if out of memory
506 */
507static errno_t amap_insert_unspec(amap_t *map, inet_ep2_t *epp, void *arg,
508 amap_flags_t flags, inet_ep2_t *aepp)
509{
510 inet_ep2_t mepp;
511 errno_t rc;
512
513 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_unspec()");
514 mepp = *epp;
515
516 rc = portrng_alloc(map->unspec, epp->local.port, arg, aflags_to_pflags(flags),
517 &mepp.local.port);
518 if (rc != EOK) {
519 return rc;
520 }
521
522 *aepp = mepp;
523 return EOK;
524}
525
526/** Insert endpoint pair into map.
527 *
528 * If local endpoint is not fully specified, it is filled in (determine
529 * source address, allocate port number). Checks for conflicting endpoint pair.
530 *
531 * @param map Association map
532 * @param epp Endpoint pair, possibly with local port inet_port_any
533 * @param arg arg User value
534 * @param flags Flags
535 * @param aepp Place to store actual endpoint pair, possibly with allocated port
536 *
537 * @return EOK on success, EEXIST if conflicting epp exists,
538 * ENOMEM if out of memory
539 */
540errno_t amap_insert(amap_t *map, inet_ep2_t *epp, void *arg, amap_flags_t flags,
541 inet_ep2_t *aepp)
542{
543 bool raddr, rport, laddr, llink;
544 inet_ep2_t mepp;
545 errno_t rc;
546
547 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert()");
548
549 mepp = *epp;
550
551 /* Fill in local address? */
552 if (!inet_addr_is_any(&epp->remote.addr) &&
553 inet_addr_is_any(&epp->local.addr)) {
554 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
555 "determine local address");
556 rc = inet_get_srcaddr(&epp->remote.addr, 0, &mepp.local.addr);
557 if (rc != EOK) {
558 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
559 "cannot determine local address");
560 return rc;
561 }
562 } else {
563 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
564 "local address specified or remote address not specified");
565 }
566
567 raddr = !inet_addr_is_any(&mepp.remote.addr);
568 rport = mepp.remote.port != inet_port_any;
569 laddr = !inet_addr_is_any(&mepp.local.addr);
570 llink = mepp.local_link != 0;
571
572 if (raddr && rport && laddr && !llink) {
573 return amap_insert_repla(map, &mepp, arg, flags, aepp);
574 } else if (!raddr && !rport && laddr && !llink) {
575 return amap_insert_laddr(map, &mepp, arg, flags, aepp);
576 } else if (!raddr && !rport && !laddr && llink) {
577 return amap_insert_llink(map, &mepp, arg, flags, aepp);
578 } else if (!raddr && !rport && !laddr && !llink) {
579 return amap_insert_unspec(map, &mepp, arg, flags, aepp);
580 } else {
581 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: invalid "
582 "combination of raddr=%d rport=%d laddr=%d llink=%d",
583 raddr, rport, laddr, llink);
584 return EINVAL;
585 }
586
587 return EOK;
588}
589
590/** Remove endpoint pair using repla as key from map.
591 *
592 * The endpoint pair must be present in the map, otherwise behavior
593 * is unspecified.
594 *
595 * @param map Association map
596 * @param epp Endpoint pair
597 */
598static void amap_remove_repla(amap_t *map, inet_ep2_t *epp)
599{
600 amap_repla_t *repla;
601 errno_t rc;
602
603 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
604 if (rc != EOK) {
605 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_repla: not found");
606 return;
607 }
608
609 portrng_free_port(repla->portrng, epp->local.port);
610
611 if (portrng_empty(repla->portrng))
612 amap_repla_remove(map, repla);
613}
614
615/** Remove endpoint pair using laddr as key from map.
616 *
617 * The endpoint pair must be present in the map, otherwise behavior
618 * is unspecified.
619 *
620 * @param map Association map
621 * @param epp Endpoint pair
622 */
623static void amap_remove_laddr(amap_t *map, inet_ep2_t *epp)
624{
625 amap_laddr_t *laddr;
626 errno_t rc;
627
628 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
629 if (rc != EOK) {
630 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_laddr: not found");
631 return;
632 }
633
634 portrng_free_port(laddr->portrng, epp->local.port);
635
636 if (portrng_empty(laddr->portrng))
637 amap_laddr_remove(map, laddr);
638}
639
640/** Remove endpoint pair using llink as key from map.
641 *
642 * The endpoint pair must be present in the map, otherwise behavior
643 * is unspecified.
644 *
645 * @param map Association map
646 * @param epp Endpoint pair
647 */
648static void amap_remove_llink(amap_t *map, inet_ep2_t *epp)
649{
650 amap_llink_t *llink;
651 errno_t rc;
652
653 rc = amap_llink_find(map, epp->local_link, &llink);
654 if (rc != EOK) {
655 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_llink: not found");
656 return;
657 }
658
659 portrng_free_port(llink->portrng, epp->local.port);
660
661 if (portrng_empty(llink->portrng))
662 amap_llink_remove(map, llink);
663}
664
665/** Remove endpoint pair using unspec as key from map.
666 *
667 * The endpoint pair must be present in the map, otherwise behavior
668 * is unspecified.
669 *
670 * @param map Association map
671 * @param epp Endpoint pair
672 */
673static void amap_remove_unspec(amap_t *map, inet_ep2_t *epp)
674{
675 portrng_free_port(map->unspec, epp->local.port);
676}
677
678/** Remove endpoint pair from map.
679 *
680 * The endpoint pair must be present in the map, otherwise behavior
681 * is unspecified.
682 *
683 * @param map Association map
684 * @param epp Endpoint pair
685 */
686void amap_remove(amap_t *map, inet_ep2_t *epp)
687{
688 bool raddr, rport, laddr, llink;
689
690 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove()");
691
692 raddr = !inet_addr_is_any(&epp->remote.addr);
693 rport = epp->remote.port != inet_port_any;
694 laddr = !inet_addr_is_any(&epp->local.addr);
695 llink = epp->local_link != 0;
696
697 if (raddr && rport && laddr && !llink) {
698 amap_remove_repla(map, epp);
699 } else if (!raddr && !rport && laddr && !llink) {
700 amap_remove_laddr(map, epp);
701 } else if (!raddr && !rport && !laddr && llink) {
702 amap_remove_llink(map, epp);
703 } else if (!raddr && !rport && !laddr && !llink) {
704 amap_remove_unspec(map, epp);
705 } else {
706 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove: invalid "
707 "combination of raddr=%d rport=%d laddr=%d llink=%d",
708 raddr, rport, laddr, llink);
709 return;
710 }
711}
712
713/** Find association matching an endpoint pair.
714 *
715 * Used to find which association to deliver a datagram to.
716 *
717 * @param map Association map
718 * @param epp Endpoint pair
719 * @param rarg Place to store user argument for the matching association.
720 *
721 * @return EOK on success, ENOENT if not found.
722 */
723errno_t amap_find_match(amap_t *map, inet_ep2_t *epp, void **rarg)
724{
725 errno_t rc;
726 amap_repla_t *repla;
727 amap_laddr_t *laddr;
728 amap_llink_t *llink;
729
730 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_find_match(llink=%zu)",
731 epp->local_link);
732
733 /* Remode endpoint, local address */
734 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
735 if (rc == EOK) {
736 rc = portrng_find_port(repla->portrng, epp->local.port,
737 rarg);
738 if (rc == EOK) {
739 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched repla / "
740 "port %" PRIu16, epp->local.port);
741 return EOK;
742 }
743 }
744
745 /* Local address */
746 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
747 if (rc == EOK) {
748 rc = portrng_find_port(laddr->portrng, epp->local.port,
749 rarg);
750 if (rc == EOK) {
751 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched laddr / "
752 "port %" PRIu16, epp->local.port);
753 return EOK;
754 }
755 }
756
757 /* Local link */
758 rc = amap_llink_find(map, epp->local_link, &llink);
759 if (epp->local_link != 0 && rc == EOK) {
760 rc = portrng_find_port(llink->portrng, epp->local.port,
761 rarg);
762 if (rc == EOK) {
763 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched llink / "
764 "port %" PRIu16, epp->local.port);
765 return EOK;
766 }
767 }
768
769 /* Unspecified */
770 rc = portrng_find_port(map->unspec, epp->local.port, rarg);
771 if (rc == EOK) {
772 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched unspec / port %" PRIu16,
773 epp->local.port);
774 return EOK;
775 }
776
777 log_msg(LOG_DEFAULT, LVL_DEBUG2, "No match.");
778 return ENOENT;
779}
780
781/**
782 * @}
783 */
Note: See TracBrowser for help on using the repository browser.