Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ab6326bc in mainline


Ignore:
Timestamp:
2015-05-28T15:31:10Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
8d48c7e
Parents:
2989c7e
Message:

Simple implementation of amap and portrng.

Location:
uspace/lib/nettl
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/nettl/include/nettl/amap.h

    r2989c7e rab6326bc  
    3737#define LIBNETTL_AMAP_H_
    3838
     39#include <adt/list.h>
    3940#include <inet/endpoint.h>
    4041#include <nettl/portrng.h>
     
    4344/** Port range for (remote endpoint, local address) */
    4445typedef struct {
     46        /** Link to amap_t.repla */
     47        link_t lamap;
    4548        /** Remote endpoint */
    4649        inet_ep_t rep;
     
    5356/** Port range for local address */
    5457typedef struct {
     58        /** Link to amap_t.laddr */
     59        link_t lamap;
    5560        /** Local address */
    5661        inet_addr_t laddr;
     
    6166/** Port range for local link */
    6267typedef struct {
     68        /** Link to amap_t.llink */
     69        link_t lamap;
    6370        /** Local link ID */
    6471        service_id_t llink;
     
    7582        /** Local links */
    7683        list_t llink; /* of amap_llink_t */
     84        /** Nothing specified (listen on all local adresses) */
     85        portrng_t *unspec;
    7786} amap_t;
    7887
  • uspace/lib/nettl/include/nettl/portrng.h

    r2989c7e rab6326bc  
    3737#define LIBNETTL_PORTRNG_H_
    3838
     39#include <stdbool.h>
    3940#include <stdint.h>
    4041
     42/** Allocated port */
    4143typedef struct {
     44        /** Link to portrng_t.used */
     45        link_t lprng;
     46        /** Port number */
     47        uint16_t pn;
     48} portrng_port_t;
     49
     50typedef struct {
     51        list_t used; /* of portrng_port_t */
    4252} portrng_t;
    4353
     
    4858extern int portrng_create(portrng_t **);
    4959extern void portrng_destroy(portrng_t *);
    50 extern int portrng_alloc_specific(portrng_t *, uint16_t, void *,
    51     portrng_flags_t);
    52 extern int portrng_alloc_dynamic(portrng_t *, void *, uint16_t *);
     60extern int portrng_alloc(portrng_t *, uint16_t, void *,
     61    portrng_flags_t, uint16_t *);
    5362extern void portrng_free_port(portrng_t *, uint16_t);
     63extern bool portrng_empty(portrng_t *);
    5464
    5565#endif
  • uspace/lib/nettl/src/amap.c

    r2989c7e rab6326bc  
    3838 */
    3939
     40#include <adt/list.h>
    4041#include <errno.h>
     42#include <inet/addr.h>
    4143#include <inet/inet.h>
    4244#include <io/log.h>
     
    4850{
    4951        amap_t *map;
    50         log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_create()");
     52        int rc;
     53
     54        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_create()");
    5155
    5256        map = calloc(1, sizeof(amap_t));
     
    5458                return ENOMEM;
    5559
     60        rc = portrng_create(&map->unspec);
     61        if (rc != EOK) {
     62                assert(rc == ENOMEM);
     63                free(map);
     64                return ENOMEM;
     65        }
     66
     67        list_initialize(&map->repla);
     68        list_initialize(&map->laddr);
     69        list_initialize(&map->llink);
     70
     71        *rmap = map;
    5672        return EOK;
    5773}
     
    5975void amap_destroy(amap_t *map)
    6076{
    61         log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_destroy()");
     77        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_destroy()");
    6278        free(map);
     79}
     80
     81/** Find exact repla */
     82static int amap_repla_find(amap_t *map, inet_ep_t *rep, inet_addr_t *la,
     83    amap_repla_t **rrepla)
     84{
     85        char *sraddr, *sladdr;
     86
     87        (void) inet_addr_format(&rep->addr, &sraddr);
     88        (void) inet_addr_format(la, &sladdr);
     89
     90        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_repla_find(): rep=(%s,%" PRIu16
     91            ") la=%s", sraddr, rep->port, sladdr);
     92        free(sraddr);
     93        free(sladdr);
     94
     95        list_foreach(map->repla, lamap, amap_repla_t, repla) {
     96                (void) inet_addr_format(&repla->rep.addr, &sraddr);
     97                (void) inet_addr_format(&repla->laddr, &sladdr);
     98                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_repla_find(): "
     99                    "compare to rep=(%s, %" PRIu16 ") la=%s",
     100                    sraddr, repla->rep.port, sladdr);
     101                free(sraddr);
     102                free(sladdr);
     103                if (inet_addr_compare(&repla->rep.addr, &rep->addr) &&
     104                    repla->rep.port == rep->port &&
     105                    inet_addr_compare(&repla->laddr, la)) {
     106                        *rrepla = repla;
     107                        return EOK;
     108                }
     109        }
     110
     111        *rrepla = NULL;
     112        return ENOENT;
     113}
     114
     115static int amap_repla_insert(amap_t *map, inet_ep_t *rep, inet_addr_t *la,
     116    amap_repla_t **rrepla)
     117{
     118        amap_repla_t *repla;
     119        int rc;
     120
     121        repla = calloc(1, sizeof(amap_repla_t));
     122        if (repla == NULL) {
     123                *rrepla = NULL;
     124                return ENOMEM;
     125        }
     126
     127        rc = portrng_create(&repla->portrng);
     128        if (rc != EOK) {
     129                free(repla);
     130                return ENOMEM;
     131        }
     132
     133        repla->rep = *rep;
     134        repla->laddr = *la;
     135        list_append(&repla->lamap, &map->repla);
     136
     137        *rrepla = repla;
     138        return EOK;
     139}
     140
     141static void amap_repla_remove(amap_t *map, amap_repla_t *repla)
     142{
     143        list_remove(&repla->lamap);
     144        portrng_destroy(repla->portrng);
     145        free(repla);
     146}
     147
     148/** Find exact laddr */
     149static int amap_laddr_find(amap_t *map, inet_addr_t *addr,
     150    amap_laddr_t **rladdr)
     151{
     152        list_foreach(map->laddr, lamap, amap_laddr_t, laddr) {
     153                if (inet_addr_compare(&laddr->laddr, addr)) {
     154                        *rladdr = laddr;
     155                        return EOK;
     156                }
     157        }
     158
     159        *rladdr = NULL;
     160        return ENOENT;
     161}
     162
     163static int amap_laddr_insert(amap_t *map, inet_addr_t *addr,
     164    amap_laddr_t **rladdr)
     165{
     166        amap_laddr_t *laddr;
     167        int rc;
     168
     169        laddr = calloc(1, sizeof(amap_laddr_t));
     170        if (laddr == NULL) {
     171                *rladdr = NULL;
     172                return ENOMEM;
     173        }
     174
     175        rc = portrng_create(&laddr->portrng);
     176        if (rc != EOK) {
     177                free(laddr);
     178                return ENOMEM;
     179        }
     180
     181        laddr->laddr = *addr;
     182        list_append(&laddr->lamap, &map->laddr);
     183
     184        *rladdr = laddr;
     185        return EOK;
     186}
     187
     188static void amap_laddr_remove(amap_t *map, amap_laddr_t *laddr)
     189{
     190        list_remove(&laddr->lamap);
     191        portrng_destroy(laddr->portrng);
     192        free(laddr);
     193}
     194
     195/** Find exact llink */
     196static int amap_llink_find(amap_t *map, sysarg_t link_id,
     197    amap_llink_t **rllink)
     198{
     199        list_foreach(map->llink, lamap, amap_llink_t, llink) {
     200                if (llink->llink == link_id) {
     201                        *rllink = llink;
     202                        return EOK;
     203                }
     204        }
     205
     206        *rllink = NULL;
     207        return ENOENT;
     208}
     209
     210static int amap_llink_insert(amap_t *map, sysarg_t link_id,
     211    amap_llink_t **rllink)
     212{
     213        amap_llink_t *llink;
     214        int rc;
     215
     216        llink = calloc(1, sizeof(amap_llink_t));
     217        if (llink == NULL) {
     218                *rllink = NULL;
     219                return ENOMEM;
     220        }
     221
     222        rc = portrng_create(&llink->portrng);
     223        if (rc != EOK) {
     224                free(llink);
     225                return ENOMEM;
     226        }
     227
     228        llink->llink = link_id;
     229        list_append(&llink->lamap, &map->llink);
     230
     231        *rllink = llink;
     232        return EOK;
     233}
     234
     235static void amap_llink_remove(amap_t *map, amap_llink_t *llink)
     236{
     237        list_remove(&llink->lamap);
     238        portrng_destroy(llink->portrng);
     239        free(llink);
     240}
     241
     242static int amap_insert_repla(amap_t *map, inet_ep2_t *epp, void *arg,
     243    amap_flags_t flags, inet_ep2_t *aepp)
     244{
     245        amap_repla_t *repla;
     246        inet_ep2_t mepp;
     247        int rc;
     248
     249        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert_repla()");
     250
     251        rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
     252        if (rc != EOK) {
     253                /* New repla */
     254                rc = amap_repla_insert(map, &epp->remote, &epp->local.addr,
     255                    &repla);
     256                if (rc != EOK) {
     257                        assert(rc == ENOMEM);
     258                        return rc;
     259                }
     260        }
     261
     262        mepp = *epp;
     263
     264        rc = portrng_alloc(repla->portrng, epp->local.port, arg, flags,
     265            &mepp.local.port);
     266        if (rc != EOK) {
     267                return rc;
     268        }
     269
     270        *aepp = mepp;
     271        return EOK;
     272}
     273
     274static int amap_insert_laddr(amap_t *map, inet_ep2_t *epp, void *arg,
     275    amap_flags_t flags, inet_ep2_t *aepp)
     276{
     277        amap_laddr_t *laddr;
     278        inet_ep2_t mepp;
     279        int rc;
     280
     281        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert_laddr()");
     282
     283        rc = amap_laddr_find(map, &epp->local.addr, &laddr);
     284        if (rc != EOK) {
     285                /* New laddr */
     286                rc = amap_laddr_insert(map, &epp->local.addr, &laddr);
     287                if (rc != EOK) {
     288                        assert(rc == ENOMEM);
     289                        return rc;
     290                }
     291        }
     292
     293        mepp = *epp;
     294
     295        rc = portrng_alloc(laddr->portrng, epp->local.port, arg, flags,
     296            &mepp.local.port);
     297        if (rc != EOK) {
     298                return rc;
     299        }
     300
     301        *aepp = mepp;
     302        return EOK;
     303}
     304
     305static int amap_insert_llink(amap_t *map, inet_ep2_t *epp, void *arg,
     306    amap_flags_t flags, inet_ep2_t *aepp)
     307{
     308        amap_llink_t *llink;
     309        inet_ep2_t mepp;
     310        int rc;
     311
     312        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert_llink()");
     313
     314        rc = amap_llink_find(map, epp->local_link, &llink);
     315        if (rc != EOK) {
     316                /* New llink */
     317                rc = amap_llink_insert(map, epp->local_link, &llink);
     318                if (rc != EOK) {
     319                        assert(rc == ENOMEM);
     320                        return rc;
     321                }
     322        }
     323
     324        mepp = *epp;
     325
     326        rc = portrng_alloc(llink->portrng, epp->local.port, arg, flags,
     327            &mepp.local.port);
     328        if (rc != EOK) {
     329                return rc;
     330        }
     331
     332        *aepp = mepp;
     333        return EOK;
     334}
     335
     336static int amap_insert_unspec(amap_t *map, inet_ep2_t *epp, void *arg,
     337    amap_flags_t flags, inet_ep2_t *aepp)
     338{
     339        inet_ep2_t mepp;
     340        int rc;
     341
     342        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert_unspec()");
     343        mepp = *epp;
     344
     345        rc = portrng_alloc(map->unspec, epp->local.port, arg, flags,
     346            &mepp.local.port);
     347        if (rc != EOK) {
     348                return rc;
     349        }
     350
     351        *aepp = mepp;
     352        return EOK;
    63353}
    64354
     
    80370    inet_ep2_t *aepp)
    81371{
    82         int rc;
    83 
    84         log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_insert()");
    85 
    86         *aepp = *epp;
     372        bool raddr, rport, laddr, llink;
     373        inet_ep2_t mepp;
     374        int rc;
     375
     376        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert()");
     377
     378        mepp = *epp;
    87379
    88380        /* Fill in local address? */
    89381        if (!inet_addr_is_any(&epp->remote.addr) &&
    90382            inet_addr_is_any(&epp->local.addr)) {
    91                 log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_insert: "
     383                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert: "
    92384                    "determine local address");
    93                 rc = inet_get_srcaddr(&epp->remote.addr, 0, &aepp->local.addr);
     385                rc = inet_get_srcaddr(&epp->remote.addr, 0, &mepp.local.addr);
    94386                if (rc != EOK) {
    95                         log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_insert: "
     387                        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert: "
    96388                            "cannot determine local address");
    97389                        return rc;
    98390                }
    99391        } else {
    100                 log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_insert: "
     392                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert: "
    101393                    "local address specified or remote address not specified");
    102394        }
    103395
    104396        /** Allocate local port? */
    105         if (aepp->local.port == inet_port_any) {
    106                 aepp->local.port = inet_port_dyn_lo; /* XXX */
    107                 log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_insert: allocated local "
    108                     "port %" PRIu16, aepp->local.port);
     397        if (mepp.local.port == inet_port_any) {
     398                mepp.local.port = inet_port_dyn_lo; /* XXX */
     399                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert: allocated local "
     400                    "port %" PRIu16, mepp.local.port);
    109401        } else {
    110                 log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_insert: local "
    111                     "port %" PRIu16 " specified", aepp->local.port);
    112         }
    113 
    114         return EOK;
     402                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert: local "
     403                    "port %" PRIu16 " specified", mepp.local.port);
     404        }
     405
     406        raddr = !inet_addr_is_any(&mepp.remote.addr);
     407        rport = mepp.remote.port != inet_port_any;
     408        laddr = !inet_addr_is_any(&mepp.local.addr);
     409        llink = mepp.local_link != 0;
     410
     411        if (raddr && rport && laddr && !llink) {
     412                return amap_insert_repla(map, &mepp, arg, flags, aepp);
     413        } else if (!raddr && !rport && laddr && !llink) {
     414                return amap_insert_laddr(map, &mepp, arg, flags, aepp);
     415        } else if (!raddr && !rport && !laddr && llink) {
     416                return amap_insert_llink(map, &mepp, arg, flags, aepp);
     417        } else if (!raddr && !rport && !laddr && !llink) {
     418                return amap_insert_unspec(map, &mepp, arg, flags, aepp);
     419        } else {
     420                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_insert: invalid "
     421                    "combination of raddr=%d rport=%d laddr=%d llink=%d",
     422                    raddr, rport, laddr, llink);
     423                return EINVAL;
     424        }
     425
     426        return EOK;
     427}
     428
     429static void amap_remove_repla(amap_t *map, inet_ep2_t *epp)
     430{
     431        amap_repla_t *repla;
     432        int rc;
     433
     434        rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
     435        if (rc != EOK) {
     436                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_remove_repla: not found");
     437                return;
     438        }
     439
     440        portrng_free_port(repla->portrng, epp->local.port);
     441
     442        if (portrng_empty(repla->portrng))
     443                amap_repla_remove(map, repla);
     444}
     445
     446static void amap_remove_laddr(amap_t *map, inet_ep2_t *epp)
     447{
     448        amap_laddr_t *laddr;
     449        int rc;
     450
     451        rc = amap_laddr_find(map, &epp->local.addr, &laddr);
     452        if (rc != EOK) {
     453                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_remove_laddr: not found");
     454                return;
     455        }
     456
     457        portrng_free_port(laddr->portrng, epp->local.port);
     458
     459        if (portrng_empty(laddr->portrng))
     460                amap_laddr_remove(map, laddr);
     461}
     462
     463static void amap_remove_llink(amap_t *map, inet_ep2_t *epp)
     464{
     465        amap_llink_t *llink;
     466        int rc;
     467
     468        rc = amap_llink_find(map, epp->local_link, &llink);
     469        if (rc != EOK) {
     470                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_remove_llink: not found");
     471                return;
     472        }
     473
     474        portrng_free_port(llink->portrng, epp->local.port);
     475
     476        if (portrng_empty(llink->portrng))
     477                amap_llink_remove(map, llink);
     478}
     479
     480static void amap_remove_unspec(amap_t *map, inet_ep2_t *epp)
     481{
     482        portrng_free_port(map->unspec, epp->local.port);
    115483}
    116484
    117485void amap_remove(amap_t *map, inet_ep2_t *epp)
    118486{
    119         log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_remove()");
     487        bool raddr, rport, laddr, llink;
     488
     489        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_remove()");
     490
     491        raddr = !inet_addr_is_any(&epp->remote.addr);
     492        rport = epp->remote.port != inet_port_any;
     493        laddr = !inet_addr_is_any(&epp->local.addr);
     494        llink = epp->local_link != 0;
     495
     496        if (raddr && rport && laddr && !llink) {
     497                amap_remove_repla(map, epp);
     498        } else if (!raddr && !rport && laddr && !llink) {
     499                amap_remove_laddr(map, epp);
     500        } else if (!raddr && !rport && !laddr && llink) {
     501                amap_remove_llink(map, epp);
     502        } else if (!raddr && !rport && !laddr && !llink) {
     503                amap_remove_unspec(map, epp);
     504        } else {
     505                log_msg(LOG_DEFAULT, LVL_NOTE, "amap_remove: invalid "
     506                    "combination of raddr=%d rport=%d laddr=%d llink=%d",
     507                    raddr, rport, laddr, llink);
     508                return;
     509        }
    120510}
    121511
    122512int amap_find(amap_t *map, inet_ep2_t *epp, void **rarg)
    123513{
    124         log_msg(LOG_DEFAULT, LVL_DEBUG, "amap_find()");
     514        log_msg(LOG_DEFAULT, LVL_NOTE, "amap_find()");
    125515        return EOK;
    126516}
  • uspace/lib/nettl/src/portrng.c

    r2989c7e rab6326bc  
    3737 */
    3838
     39#include <adt/list.h>
    3940#include <errno.h>
     41#include <inet/endpoint.h>
    4042#include <nettl/portrng.h>
    4143#include <stdint.h>
     44#include <stdlib.h>
     45
     46#include <io/log.h>
    4247
    4348int portrng_create(portrng_t **rpr)
    4449{
     50        portrng_t *pr;
     51
     52        log_msg(LOG_DEFAULT, LVL_NOTE, "portrng_create() - begin");
     53
     54        pr = calloc(1, sizeof(portrng_t));
     55        if (pr == NULL)
     56                return ENOMEM;
     57
     58        list_initialize(&pr->used);
     59        *rpr = pr;
     60        log_msg(LOG_DEFAULT, LVL_NOTE, "portrng_create() - end");
    4561        return EOK;
    4662}
     
    4864void portrng_destroy(portrng_t *pr)
    4965{
     66        log_msg(LOG_DEFAULT, LVL_NOTE, "portrng_destroy()");
     67        assert(list_empty(&pr->used));
     68        free(pr);
    5069}
    5170
    52 int portrng_alloc_specific(portrng_t *pr, uint16_t pnum, void *arg,
    53     portrng_flags_t flags)
     71int portrng_alloc(portrng_t *pr, uint16_t pnum, void *arg,
     72    portrng_flags_t flags, uint16_t *apnum)
    5473{
    55         return EOK;
    56 }
     74        portrng_port_t *p;
     75        uint32_t i;
     76        bool found;
    5777
    58 int portrng_alloc_dynamic(portrng_t *pr, void *arg, uint16_t *rpnum)
    59 {
     78        log_msg(LOG_DEFAULT, LVL_NOTE, "portrng_alloc() - begin");
     79
     80        if (pnum == inet_port_any) {
     81
     82                for (i = inet_port_dyn_lo; i <= inet_port_dyn_hi; i++) {
     83                        log_msg(LOG_DEFAULT, LVL_NOTE, "trying %" PRIu32, i);
     84                        found = false;
     85                        list_foreach(pr->used, lprng, portrng_port_t, port) {
     86                                if (port->pn == pnum) {
     87                                        found = true;
     88                                        break;
     89                                }
     90                        }
     91
     92                        if (!found) {
     93                                pnum = i;
     94                                break;
     95                        }
     96                }
     97
     98                if (pnum == inet_port_any) {
     99                        /* No free port found */
     100                        return ENOENT;
     101                }
     102                log_msg(LOG_DEFAULT, LVL_NOTE, "selected %" PRIu16, pnum);
     103        } else {
     104                if ((flags & pf_allow_system) == 0 &&
     105                    pnum < inet_port_user_lo) {
     106                        return EINVAL;
     107                }
     108
     109                list_foreach(pr->used, lprng, portrng_port_t, port) {
     110                        if (port->pn == pnum)
     111                                return EEXISTS;
     112                }
     113        }
     114
     115        p = calloc(1, sizeof(portrng_port_t));
     116        if (p == NULL)
     117                return ENOMEM;
     118
     119        p->pn = pnum;
     120        list_append(&p->lprng, &pr->used);
     121        *apnum = pnum;
     122        log_msg(LOG_DEFAULT, LVL_NOTE, "portrng_alloc() - end OK pn=%" PRIu16,
     123            pnum);
    60124        return EOK;
    61125}
     
    63127void portrng_free_port(portrng_t *pr, uint16_t pnum)
    64128{
     129        log_msg(LOG_DEFAULT, LVL_NOTE, "portrng_free_port() - begin");
     130        list_foreach(pr->used, lprng, portrng_port_t, port) {
     131                if (port->pn == pnum) {
     132                        list_remove(&port->lprng);
     133                        free(port);
     134                        return;
     135                }
     136        }
     137
     138        assert(false);
     139        log_msg(LOG_DEFAULT, LVL_NOTE, "portrng_free_port() - end");
     140}
     141
     142bool portrng_empty(portrng_t *pr)
     143{
     144        log_msg(LOG_DEFAULT, LVL_NOTE, "portrng_empty()");
     145        return list_empty(&pr->used);
    65146}
    66147
Note: See TracChangeset for help on using the changeset viewer.