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

Changeset ee1c2d9 in mainline


Ignore:
Timestamp:
2015-06-13T18:30:18Z (6 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
master
Children:
a157846
Parents:
0453261 (diff), 2f9a8e8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

mainline changes

Files:
10 added
40 deleted
63 edited
7 moved

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/synch/futex.c

    r0453261 ree1c2d9  
    400400                return (sysarg_t) ENOENT;
    401401
     402#ifdef CONFIG_UDEBUG
     403        udebug_stoppable_begin();
     404#endif
     405
    402406        int rc = waitq_sleep_timeout(&futex->wq, 0, SYNCH_FLAGS_INTERRUPTIBLE);
     407
     408#ifdef CONFIG_UDEBUG
     409        udebug_stoppable_end();
     410#endif
    403411
    404412        return (sysarg_t) rc;
  • uspace/Makefile

    r0453261 ree1c2d9  
    7777        app/usbinfo \
    7878        app/vuhid \
    79         app/netecho \
    80         app/netspeed \
    81         app/nettest1 \
    82         app/nettest2 \
    83         app/nettest3 \
    8479        app/nic \
    8580        app/ping \
     
    234229        lib/draw \
    235230        lib/math \
    236         lib/net \
     231        lib/nettl \
    237232        lib/nic \
    238233        lib/ext4 \
  • uspace/Makefile.common

    r0453261 ree1c2d9  
    142142LIBHOUND_PREFIX = $(LIB_PREFIX)/hound
    143143LIBPCM_PREFIX = $(LIB_PREFIX)/pcm
    144 LIBNET_PREFIX = $(LIB_PREFIX)/net
    145144LIBNIC_PREFIX = $(LIB_PREFIX)/nic
    146145LIBIEEE80211_PREFIX = $(LIB_PREFIX)/ieee80211
     
    158157LIBMBR_PREFIX = $(LIB_PREFIX)/mbr
    159158LIBGPT_PREFIX = $(LIB_PREFIX)/gpt
     159LIBNETTL_PREFIX = $(LIB_PREFIX)/nettl
    160160
    161161LIBURCU_PREFIX = $(LIB_PREFIX)/urcu
     
    264264
    265265ifeq ($(CONFIG_LINE_DEBUG),y)
    266         GCC_CFLAGS += -g
     266        GCC_CFLAGS += -ggdb
    267267        ICC_CFLAGS += -g
    268268        CLANG_CFLAGS += -g
  • uspace/app/download/main.c

    r0453261 ree1c2d9  
    3636 */
    3737
     38#include <errno.h>
    3839#include <stdio.h>
    3940#include <stdlib.h>
     
    4243#include <task.h>
    4344#include <macros.h>
    44 
    45 #include <net/in.h>
    46 #include <net/inet.h>
    47 #include <net/socket.h>
    4845
    4946#include <http/http.h>
  • uspace/app/nterm/conn.c

    r0453261 ree1c2d9  
    3838#include <fibril.h>
    3939#include <inet/dnsr.h>
    40 #include <net/inet.h>
    41 #include <net/socket.h>
     40#include <inet/endpoint.h>
     41#include <inet/tcp.h>
    4242#include <stdio.h>
    4343#include <stdlib.h>
     
    4848#include "nterm.h"
    4949
    50 static int conn_fd;
    51 static fid_t rcv_fid;
     50static tcp_t *tcp;
     51static tcp_conn_t *conn;
    5252
    5353#define RECV_BUF_SIZE 1024
    5454static uint8_t recv_buf[RECV_BUF_SIZE];
    5555
    56 static int rcv_fibril(void *arg)
     56static void conn_conn_reset(tcp_conn_t *);
     57static void conn_data_avail(tcp_conn_t *);
     58
     59static tcp_cb_t conn_cb = {
     60        .conn_reset = conn_conn_reset,
     61        .data_avail = conn_data_avail
     62};
     63
     64static void conn_conn_reset(tcp_conn_t *conn)
    5765{
    58         ssize_t nr;
     66        printf("\n[Connection reset]\n");
     67}
     68
     69static void conn_data_avail(tcp_conn_t *conn)
     70{
     71        int rc;
     72        size_t nrecv;
    5973
    6074        while (true) {
    61                 nr = recv(conn_fd, recv_buf, RECV_BUF_SIZE, 0);
    62                 if (nr < 0)
     75                rc = tcp_conn_recv(conn, recv_buf, RECV_BUF_SIZE, &nrecv);
     76                if (rc != EOK) {
     77                        printf("\n[Receive error %d]\n", rc);
    6378                        break;
     79                }
    6480
    65                 nterm_received(recv_buf, nr);
     81                nterm_received(recv_buf, nrecv);
     82
     83                if (nrecv != RECV_BUF_SIZE)
     84                        break;
    6685        }
    67 
    68         if (nr == ENOTCONN)
    69                 printf("\n[Other side has closed the connection]\n");
    70         else
    71                 printf("'\n[Receive errror (%s)]\n", str_error(nr));
    72 
    73         exit(0);
    74         return 0;
    7586}
    7687
    7788int conn_open(const char *host, const char *port_s)
    7889{
    79         int conn_fd = -1;
    80         struct sockaddr *saddr = NULL;
    81         socklen_t saddrlen;
    82        
     90        inet_ep2_t epp;
     91
    8392        /* Interpret as address */
    8493        inet_addr_t iaddr;
    8594        int rc = inet_addr_parse(host, &iaddr);
    86        
     95
    8796        if (rc != EOK) {
    8897                /* Interpret as a host name */
    8998                dnsr_hostinfo_t *hinfo = NULL;
    9099                rc = dnsr_name2host(host, &hinfo, ip_any);
    91                
     100
    92101                if (rc != EOK) {
    93102                        printf("Error resolving host '%s'.\n", host);
    94103                        goto error;
    95104                }
    96                
     105
    97106                iaddr = hinfo->addr;
    98107        }
    99        
     108
    100109        char *endptr;
    101110        uint16_t port = strtol(port_s, &endptr, 10);
     
    104113                goto error;
    105114        }
    106        
    107         rc = inet_addr_sockaddr(&iaddr, port, &saddr, &saddrlen);
    108         if (rc != EOK) {
    109                 assert(rc == ENOMEM);
    110                 printf("Out of memory.\n");
    111                 return ENOMEM;
    112         }
    113        
     115
     116        inet_ep2_init(&epp);
     117        epp.remote.addr = iaddr;
     118        epp.remote.port = port;
     119
    114120        printf("Connecting to host %s port %u\n", host, port);
    115        
    116         conn_fd = socket(saddr->sa_family, SOCK_STREAM, 0);
    117         if (conn_fd < 0)
    118                 goto error;
    119        
    120         rc = connect(conn_fd, saddr, saddrlen);
     121
     122        rc = tcp_create(&tcp);
    121123        if (rc != EOK)
    122124                goto error;
    123        
    124         rcv_fid = fibril_create(rcv_fibril, NULL);
    125         if (rcv_fid == 0)
     125
     126        rc = tcp_conn_create(tcp, &epp, &conn_cb, NULL, &conn);
     127        if (rc != EOK)
    126128                goto error;
    127        
    128         fibril_add_ready(rcv_fid);
    129        
    130         free(saddr);
     129
     130        rc = tcp_conn_wait_connected(conn);
     131        if (rc != EOK)
     132                goto error;
     133
    131134        return EOK;
    132135error:
    133         if (conn_fd >= 0) {
    134                 closesocket(conn_fd);
    135                 conn_fd = -1;
    136         }
    137         free(saddr);
    138        
     136        tcp_conn_destroy(conn);
     137        tcp_destroy(tcp);
     138
    139139        return EIO;
    140140}
     
    142142int conn_send(void *data, size_t size)
    143143{
    144         int rc = send(conn_fd, data, size, 0);
     144        int rc = tcp_conn_send(conn, data, size);
    145145        if (rc != EOK)
    146146                return EIO;
    147        
     147
    148148        return EOK;
    149149}
  • uspace/app/websrv/websrv.c

    r0453261 ree1c2d9  
    4444#include <task.h>
    4545
    46 #include <net/in.h>
    47 #include <net/inet.h>
    48 #include <net/socket.h>
     46#include <inet/addr.h>
     47#include <inet/endpoint.h>
     48#include <inet/tcp.h>
    4949
    5050#include <arg_parse.h>
     
    5656
    5757#define DEFAULT_PORT  8080
    58 #define BACKLOG_SIZE  3
    5958
    6059#define WEB_ROOT  "/data/web"
     
    6261/** Buffer for receiving the request. */
    6362#define BUFFER_SIZE  1024
     63
     64static void websrv_new_conn(tcp_listener_t *, tcp_conn_t *);
     65
     66static tcp_listen_cb_t listen_cb = {
     67        .new_conn = websrv_new_conn
     68};
     69
     70static tcp_cb_t conn_cb = {
     71        .connected = NULL
     72};
    6473
    6574static uint16_t port = DEFAULT_PORT;
     
    122131
    123132/** Receive one character (with buffering) */
    124 static int recv_char(int fd, char *c)
    125 {
     133static int recv_char(tcp_conn_t *conn, char *c)
     134{
     135        size_t nrecv;
     136        int rc;
     137       
    126138        if (rbuf_out == rbuf_in) {
    127139                rbuf_out = 0;
    128140                rbuf_in = 0;
    129141               
    130                 ssize_t rc = recv(fd, rbuf, BUFFER_SIZE, 0);
    131                 if (rc <= 0) {
    132                         fprintf(stderr, "recv() failed (%zd)\n", rc);
     142                rc = tcp_conn_recv_wait(conn, rbuf, BUFFER_SIZE, &nrecv);
     143                if (rc != EOK) {
     144                        fprintf(stderr, "tcp_conn_recv() failed (%d)\n", rc);
    133145                        return rc;
    134146                }
    135147               
    136                 rbuf_in = rc;
     148                rbuf_in = nrecv;
    137149        }
    138150       
     
    142154
    143155/** Receive one line with length limit */
    144 static int recv_line(int fd)
     156static int recv_line(tcp_conn_t *conn)
    145157{
    146158        char *bp = lbuf;
     
    149161        while (bp < lbuf + BUFFER_SIZE) {
    150162                char prev = c;
    151                 int rc = recv_char(fd, &c);
     163                int rc = recv_char(conn, &c);
    152164               
    153165                if (rc != EOK)
     
    187199}
    188200
    189 static int send_response(int conn_sd, const char *msg)
     201static int send_response(tcp_conn_t *conn, const char *msg)
    190202{
    191203        size_t response_size = str_size(msg);
     
    194206            fprintf(stderr, "Sending response\n");
    195207       
    196         ssize_t rc = send(conn_sd, (void *) msg, response_size, 0);
    197         if (rc < 0) {
    198                 fprintf(stderr, "send() failed\n");
     208        int rc = tcp_conn_send(conn, (void *) msg, response_size);
     209        if (rc != EOK) {
     210                fprintf(stderr, "tcp_conn_send() failed\n");
    199211                return rc;
    200212        }
     
    203215}
    204216
    205 static int uri_get(const char *uri, int conn_sd)
     217static int uri_get(const char *uri, tcp_conn_t *conn)
    206218{
    207219        if (str_cmp(uri, "/") == 0)
     
    215227        int fd = open(fname, O_RDONLY);
    216228        if (fd < 0) {
    217                 rc = send_response(conn_sd, msg_not_found);
     229                rc = send_response(conn, msg_not_found);
    218230                free(fname);
    219231                return rc;
     
    222234        free(fname);
    223235       
    224         rc = send_response(conn_sd, msg_ok);
     236        rc = send_response(conn, msg_ok);
    225237        if (rc != EOK)
    226238                return rc;
     
    236248                }
    237249               
    238                 rc = send(conn_sd, fbuf, nr, 0);
    239                 if (rc < 0) {
    240                         fprintf(stderr, "send() failed\n");
     250                rc = tcp_conn_send(conn, fbuf, nr);
     251                if (rc != EOK) {
     252                        fprintf(stderr, "tcp_conn_send() failed\n");
    241253                        close(fd);
    242254                        return rc;
     
    249261}
    250262
    251 static int req_process(int conn_sd)
    252 {
    253         int rc = recv_line(conn_sd);
     263static int req_process(tcp_conn_t *conn)
     264{
     265        int rc = recv_line(conn);
    254266        if (rc != EOK) {
    255267                fprintf(stderr, "recv_line() failed\n");
     
    261273       
    262274        if (str_lcmp(lbuf, "GET ", 4) != 0) {
    263                 rc = send_response(conn_sd, msg_not_implemented);
     275                rc = send_response(conn, msg_not_implemented);
    264276                return rc;
    265277        }
     
    277289       
    278290        if (!uri_is_valid(uri)) {
    279                 rc = send_response(conn_sd, msg_bad_request);
    280                 return rc;
    281         }
    282        
    283         return uri_get(uri, conn_sd);
     291                rc = send_response(conn, msg_bad_request);
     292                return rc;
     293        }
     294       
     295        return uri_get(uri, conn);
    284296}
    285297
     
    346358}
    347359
     360static void websrv_new_conn(tcp_listener_t *lst, tcp_conn_t *conn)
     361{
     362        int rc;
     363       
     364        if (verbose)
     365                fprintf(stderr, "New connection, waiting for request\n");
     366       
     367        rbuf_out = 0;
     368        rbuf_in = 0;
     369       
     370        rc = req_process(conn);
     371        if (rc != EOK) {
     372                fprintf(stderr, "Error processing request (%s)\n",
     373                    str_error(rc));
     374                return;
     375        }
     376
     377        rc = tcp_conn_send_fin(conn);
     378        if (rc != EOK) {
     379                fprintf(stderr, "Error sending FIN.\n");
     380                return;
     381        }
     382}
     383
    348384int main(int argc, char *argv[])
    349385{
     386        inet_ep_t ep;
     387        tcp_listener_t *lst;
     388        tcp_t *tcp;
     389        int rc;
     390       
    350391        /* Parse command line arguments */
    351392        for (int i = 1; i < argc; i++) {
    352393                if (argv[i][0] == '-') {
    353                         int rc = parse_option(argc, argv, &i);
     394                        rc = parse_option(argc, argv, &i);
    354395                        if (rc != EOK)
    355396                                return rc;
     
    360401        }
    361402       
    362         struct sockaddr_in addr;
    363        
    364         addr.sin_family = AF_INET;
    365         addr.sin_port = htons(port);
    366        
    367         int rc = inet_pton(AF_INET, "127.0.0.1", (void *)
    368             &addr.sin_addr.s_addr);
    369         if (rc != EOK) {
    370                 fprintf(stderr, "Error parsing network address (%s)\n",
    371                     str_error(rc));
     403        printf("%s: HelenOS web server\n", NAME);
     404
     405        if (verbose)
     406                fprintf(stderr, "Creating listener\n");
     407       
     408        inet_ep_init(&ep);
     409        ep.port = port;
     410
     411        rc = tcp_create(&tcp);
     412        if (rc != EOK) {
     413                fprintf(stderr, "Error initializing TCP.\n");
    372414                return 1;
    373415        }
    374        
    375         printf("%s: HelenOS web server\n", NAME);
    376 
    377         if (verbose)
    378                 fprintf(stderr, "Creating socket\n");
    379        
    380         int listen_sd = socket(PF_INET, SOCK_STREAM, 0);
    381         if (listen_sd < 0) {
    382                 fprintf(stderr, "Error creating listening socket (%s)\n",
    383                     str_error(listen_sd));
     416
     417        rc = tcp_listener_create(tcp, &ep, &listen_cb, NULL, &conn_cb, NULL,
     418            &lst);
     419        if (rc != EOK) {
     420                fprintf(stderr, "Error creating listener.\n");
    384421                return 2;
    385         }
    386        
    387         rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
    388         if (rc != EOK) {
    389                 fprintf(stderr, "Error binding socket (%s)\n",
    390                     str_error(rc));
    391                 return 3;
    392         }
    393        
    394         rc = listen(listen_sd, BACKLOG_SIZE);
    395         if (rc != EOK) {
    396                 fprintf(stderr, "listen() failed (%s)\n", str_error(rc));
    397                 return 4;
    398422        }
    399423       
     
    402426
    403427        task_retval(0);
    404 
    405         while (true) {
    406                 struct sockaddr_in raddr;
    407                 socklen_t raddr_len = sizeof(raddr);
    408                 int conn_sd = accept(listen_sd, (struct sockaddr *) &raddr,
    409                     &raddr_len);
    410                
    411                 if (conn_sd < 0) {
    412                         fprintf(stderr, "accept() failed (%s)\n", str_error(rc));
    413                         continue;
    414                 }
    415                
    416                 if (verbose) {
    417                         fprintf(stderr, "Connection accepted (sd=%d), "
    418                             "waiting for request\n", conn_sd);
    419                 }
    420                
    421                 rbuf_out = 0;
    422                 rbuf_in = 0;
    423                
    424                 rc = req_process(conn_sd);
    425                 if (rc != EOK)
    426                         fprintf(stderr, "Error processing request (%s)\n",
    427                             str_error(rc));
    428                
    429                 rc = closesocket(conn_sd);
    430                 if (rc != EOK) {
    431                         fprintf(stderr, "Error closing connection socket (%s)\n",
    432                             str_error(rc));
    433                         closesocket(listen_sd);
    434                         return 5;
    435                 }
    436                
    437                 if (verbose)
    438                         fprintf(stderr, "Connection closed\n");
    439         }
     428        async_manager();
    440429       
    441430        /* Not reached */
  • uspace/drv/bus/usb/usbhub/usbhub.c

    r0453261 ree1c2d9  
    191191                if (!tries--) {
    192192                        usb_log_error("Can't remove hub, still running.\n");
    193                         return EINPROGRESS;
     193                        return EBUSY;
    194194                }
    195195        }
  • uspace/lib/c/Makefile

    r0453261 ree1c2d9  
    9797        generic/futex.c \
    9898        generic/inet/addr.c \
     99        generic/inet/endpoint.c \
     100        generic/inet/tcp.c \
     101        generic/inet/udp.c \
    99102        generic/inet.c \
    100103        generic/inetcfg.c \
     
    137140        generic/adt/list.c \
    138141        generic/adt/hash_table.c \
    139         generic/adt/dynamic_fifo.c \
    140         generic/adt/char_map.c \
    141142        generic/adt/prodcons.c \
    142143        generic/time.c \
     
    145146        generic/vfs/vfs.c \
    146147        generic/vfs/canonify.c \
    147         generic/net/inet.c \
    148         generic/net/socket_client.c \
    149         generic/net/socket_parse.c \
    150148        generic/setjmp.c \
    151149        generic/stack.c \
  • uspace/lib/c/generic/fibril_synch.c

    r0453261 ree1c2d9  
    461461                        if (rc == ETIMEOUT && timer->state == fts_active) {
    462462                                timer->state = fts_fired;
    463                                 timer->handler_running = true;
     463                                timer->handler_fid = fibril_get_id();
    464464                                fibril_mutex_unlock(timer->lockp);
    465465                                timer->fun(timer->arg);
    466466                                fibril_mutex_lock(timer->lockp);
    467                                 timer->handler_running = false;
     467                                timer->handler_fid = 0;
    468468                        }
    469469                        break;
     
    477477        /* Acknowledge timer fibril has finished cleanup. */
    478478        timer->state = fts_clean;
     479        fibril_condvar_broadcast(&timer->cv);
    479480        fibril_mutex_unlock(timer->lockp);
    480         free(timer);
    481481
    482482        return 0;
     
    525525        timer->state = fts_cleanup;
    526526        fibril_condvar_broadcast(&timer->cv);
     527
     528        /* Wait for timer fibril to terminate */
     529        while (timer->state != fts_clean)
     530                fibril_condvar_wait(&timer->cv, timer->lockp);
    527531        fibril_mutex_unlock(timer->lockp);
     532
     533        free(timer);
    528534}
    529535
     
    608614        assert(fibril_mutex_is_locked(timer->lockp));
    609615
    610         while (timer->handler_running)
     616        while (timer->handler_fid != 0) {
     617                if (timer->handler_fid == fibril_get_id()) {
     618                        printf("Deadlock detected.\n");
     619                        stacktrace_print();
     620                        printf("Fibril %zx is trying to clear timer %p from "
     621                            "inside its handler %p.\n",
     622                            fibril_get_id(), timer, timer->fun);
     623                        abort();
     624                }
     625
    611626                fibril_condvar_wait(&timer->cv, timer->lockp);
     627        }
    612628
    613629        old_state = timer->state;
  • uspace/lib/c/generic/inet.c

    r0453261 ree1c2d9  
    177177       
    178178        dgram.tos = IPC_GET_ARG1(*icall);
     179        dgram.iplink = IPC_GET_ARG2(*icall);
    179180       
    180181        ipc_callid_t callid;
  • uspace/lib/c/generic/inet/addr.c

    r0453261 ree1c2d9  
    11/*
    22 * Copyright (c) 2013 Jiri Svoboda
     3 * Copyright (c) 2013 Martin Decky
    34 * All rights reserved.
    45 *
     
    3637#include <errno.h>
    3738#include <unistd.h>
    38 #include <net/socket_codes.h>
    3939#include <inet/addr.h>
    40 #include <net/inet.h>
    4140#include <stdio.h>
    4241#include <malloc.h>
     
    4443
    4544#define INET_PREFIXSTRSIZE  5
     45
     46#define INET6_ADDRSTRLEN (8 * 4 + 7 + 1)
    4647
    4748#if !(defined(__BE__) ^ defined(__LE__))
     
    180181}
    181182
    182 /** Determine address version.
    183  *
    184  * @param text Address in common notation.
    185  * @param af   Place to store address version.
    186  *
    187  * @return EOK on success, EINVAL if input is not in valid format.
    188  *
    189  */
    190 static int inet_addr_version(const char *text, ip_ver_t *ver)
    191 {
    192         char *dot = str_chr(text, '.');
    193         if (dot != NULL) {
    194                 *ver = ip_v4;
    195                 return EOK;
    196         }
    197 
    198         char *collon = str_chr(text, ':');
    199         if (collon != NULL) {
    200                 *ver = ip_v6;
    201                 return EOK;
    202         }
    203 
    204         return EINVAL;
    205 }
    206 
    207 static int ipver_af(ip_ver_t ver)
    208 {
    209         switch (ver) {
    210         case ip_any:
    211                 return AF_NONE;
    212         case ip_v4:
    213                 return AF_INET;
    214         case ip_v6:
    215                 return AF_INET6;
    216         default:
    217                 assert(false);
    218                 return EINVAL;
    219         }
    220 }
    221 
    222 ip_ver_t ipver_from_af(int af)
    223 {
    224         switch (af) {
    225         case AF_NONE:
    226                 return ip_any;
    227         case AF_INET:
    228                 return ip_v4;
    229         case AF_INET6:
    230                 return ip_v6;
    231         default:
    232                 assert(false);
    233                 return EINVAL;
    234         }
    235 }
    236 
    237183void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr)
    238184{
     
    288234        if (naddr->version != addr->version)
    289235                return 0;
    290        
     236
    291237        switch (naddr->version) {
    292238        case ip_v4:
     
    315261                if (naddr->prefix > 128)
    316262                        return 0;
    317                
     263
    318264                size_t pos = 0;
    319265                for (size_t i = 0; i < 16; i++) {
     
    321267                        if (naddr->prefix < pos)
    322268                                break;
    323                        
     269
    324270                        if (naddr->prefix - pos > 8) {
    325271                                /* Comparison without masking */
     
    333279                                        return 0;
    334280                        }
    335                        
     281
    336282                        pos += 8;
    337283                }
    338                
     284
    339285                return 1;
    340286        default:
     
    343289}
    344290
     291static int inet_addr_parse_v4(const char *str, inet_addr_t *raddr,
     292    int *prefix)
     293{
     294        uint32_t a = 0;
     295        uint8_t b;
     296        char *cur = (char *)str;
     297        size_t i = 0;
     298
     299        while (i < 4) {
     300                int rc = str_uint8_t(cur, (const char **)&cur, 10, false, &b);
     301                if (rc != EOK)
     302                        return rc;
     303
     304                a = (a << 8) + b;
     305
     306                i++;
     307
     308                if (*cur == '\0')
     309                        break;
     310
     311                if (*cur != '.')
     312                        return EINVAL;
     313
     314                if (i < 4)
     315                        cur++;
     316        }
     317
     318        if (prefix != NULL) {
     319                *prefix = strtoul(cur, &cur, 10);
     320                if (*prefix > 32)
     321                        return EINVAL;
     322        }
     323
     324        if (i != 4 || (*cur != '\0'))
     325                return EINVAL;
     326
     327        raddr->version = ip_v4;
     328        raddr->addr = a;
     329
     330        return EOK;
     331}
     332
     333static int inet_addr_parse_v6(const char *str, inet_addr_t *raddr, int *prefix)
     334{
     335        uint8_t data[16];
     336
     337        memset(data, 0, 16);
     338
     339        const char *cur = str;
     340        size_t i = 0;
     341        size_t wildcard_pos = (size_t) -1;
     342        size_t wildcard_size = 0;
     343
     344        /* Handle initial wildcard */
     345        if ((str[0] == ':') && (str[1] == ':')) {
     346                cur = str + 2;
     347                wildcard_pos = 0;
     348                wildcard_size = 16;
     349
     350                /* Handle the unspecified address */
     351                if (*cur == '\0')
     352                        goto success;
     353        }
     354
     355        while (i < 16) {
     356                uint16_t bioctet;
     357                int rc = str_uint16_t(cur, &cur, 16, false, &bioctet);
     358                if (rc != EOK)
     359                        return rc;
     360
     361                data[i] = (bioctet >> 8) & 0xff;
     362                data[i + 1] = bioctet & 0xff;
     363
     364                if (wildcard_pos != (size_t) -1) {
     365                        if (wildcard_size < 2)
     366                                return EINVAL;
     367
     368                        wildcard_size -= 2;
     369                }
     370
     371                i += 2;
     372
     373                if (*cur != ':')
     374                        break;
     375
     376                if (i < 16) {
     377                        cur++;
     378
     379                        /* Handle wildcard */
     380                        if (*cur == ':') {
     381                                if (wildcard_pos != (size_t) -1)
     382                                        return EINVAL;
     383
     384                                wildcard_pos = i;
     385                                wildcard_size = 16 - i;
     386                                cur++;
     387
     388                                if (*cur == '\0' || *cur == '/')
     389                                        break;
     390                        }
     391                }
     392        }
     393
     394        if (prefix != NULL) {
     395                if (*cur != '/')
     396                        return EINVAL;
     397                cur++;
     398
     399                *prefix = strtoul(cur, (char **)&cur, 10);
     400                if (*prefix > 128)
     401                        return EINVAL;
     402        }
     403
     404        if (*cur != '\0')
     405                return EINVAL;
     406
     407        /* Create wildcard positions */
     408        if ((wildcard_pos != (size_t) -1) && (wildcard_size > 0)) {
     409                size_t wildcard_shift = 16 - wildcard_size;
     410
     411                for (i = wildcard_pos + wildcard_shift; i > wildcard_pos; i--) {
     412                        size_t j = i - 1;
     413                        data[j + wildcard_size] = data[j];
     414                        data[j] = 0;
     415                }
     416        }
     417
     418success:
     419        raddr->version = ip_v6;
     420        memcpy(raddr->addr6, data, 16);
     421        return EOK;
     422}
     423
    345424/** Parse node address.
    346425 *
     
    353432int inet_addr_parse(const char *text, inet_addr_t *addr)
    354433{
    355         int rc = inet_addr_version(text, &addr->version);
    356         if (rc != EOK)
    357                 return rc;
    358        
    359         uint8_t buf[16];
    360         rc = inet_pton(ipver_af(addr->version), text, buf);
    361         if (rc != EOK)
    362                 return rc;
    363        
    364         switch (addr->version) {
    365         case ip_v4:
    366                 addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
    367                     buf[3];
    368                 break;
    369         case ip_v6:
    370                 memcpy(addr->addr6, buf, 16);
    371                 break;
    372         default:
    373                 return EINVAL;
    374         }
    375        
    376         return EOK;
     434        int rc;
     435
     436        rc = inet_addr_parse_v4(text, addr, NULL);
     437        if (rc == EOK)
     438                return EOK;
     439
     440        rc = inet_addr_parse_v6(text, addr, NULL);
     441        if (rc == EOK)
     442                return EOK;
     443
     444        return EINVAL;
    377445}
    378446
     
    387455int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
    388456{
    389         char *slash = str_chr(text, '/');
    390         if (slash == NULL)
    391                 return EINVAL;
    392        
    393         *slash = 0;
    394        
    395         int rc = inet_addr_version(text, &naddr->version);
    396         if (rc != EOK)
    397                 return rc;
    398        
    399         uint8_t buf[16];
    400         rc = inet_pton(ipver_af(naddr->version), text, buf);
    401         *slash = '/';
    402        
    403         if (rc != EOK)
    404                 return rc;
    405        
    406         slash++;
    407         uint8_t prefix;
    408        
    409         switch (naddr->version) {
    410         case ip_v4:
    411                 prefix = strtoul(slash, &slash, 10);
    412                 if (prefix > 32)
     457        int rc;
     458        inet_addr_t addr;
     459        int prefix;
     460
     461        rc = inet_addr_parse_v4(text, &addr, &prefix);
     462        if (rc == EOK) {
     463                inet_addr_naddr(&addr, prefix, naddr);
     464                return EOK;
     465        }
     466
     467        rc = inet_addr_parse_v6(text, &addr, &prefix);
     468        if (rc == EOK) {
     469                inet_addr_naddr(&addr, prefix, naddr);
     470                return EOK;
     471        }
     472
     473        return EINVAL;
     474}
     475
     476static int inet_addr_format_v4(addr32_t addr, char **bufp)
     477{
     478        int rc;
     479
     480        rc = asprintf(bufp, "%u.%u.%u.%u", (addr >> 24) & 0xff,
     481            (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
     482        if (rc < 0)
     483                return ENOMEM;
     484
     485        return EOK;
     486}
     487
     488static int inet_addr_format_v6(const addr128_t addr, char **bufp)
     489{
     490        *bufp = (char *) malloc(INET6_ADDRSTRLEN);
     491        if (*bufp == NULL)
     492                return ENOMEM;
     493
     494        /* Find the longest zero subsequence */
     495
     496        uint16_t zeroes[8];
     497        uint16_t bioctets[8];
     498
     499        for (size_t i = 8; i > 0; i--) {
     500                size_t j = i - 1;
     501
     502                bioctets[j] = (addr[j << 1] << 8) | addr[(j << 1) + 1];
     503
     504                if (bioctets[j] == 0) {
     505                        zeroes[j] = 1;
     506                        if (j < 7)
     507                                zeroes[j] += zeroes[j + 1];
     508                } else
     509                        zeroes[j] = 0;
     510        }
     511
     512        size_t wildcard_pos = (size_t) -1;
     513        size_t wildcard_size = 0;
     514
     515        for (size_t i = 0; i < 8; i++) {
     516                if (zeroes[i] > wildcard_size) {
     517                        wildcard_pos = i;
     518                        wildcard_size = zeroes[i];
     519                }
     520        }
     521
     522        char *cur = *bufp;
     523        size_t rest = INET6_ADDRSTRLEN;
     524        bool tail_zero = false;
     525        int ret;
     526
     527        for (size_t i = 0; i < 8; i++) {
     528                if ((i == wildcard_pos) && (wildcard_size > 1)) {
     529                        ret = snprintf(cur, rest, ":");
     530                        i += wildcard_size - 1;
     531                        tail_zero = true;
     532                } else if (i == 0) {
     533                        ret = snprintf(cur, rest, "%" PRIx16, bioctets[i]);
     534                        tail_zero = false;
     535                } else {
     536                        ret = snprintf(cur, rest, ":%" PRIx16, bioctets[i]);
     537                        tail_zero = false;
     538                }
     539
     540                if (ret < 0)
    413541                        return EINVAL;
    414                
    415                 naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
    416                     buf[3];
    417                 naddr->prefix = prefix;
    418                
    419                 break;
    420         case ip_v6:
    421                 prefix = strtoul(slash, &slash, 10);
    422                 if (prefix > 128)
    423                         return EINVAL;
    424                
    425                 memcpy(naddr->addr6, buf, 16);
    426                 naddr->prefix = prefix;
    427                
    428                 break;
    429         default:
    430                 return ENOTSUP;
    431         }
    432        
     542
     543                cur += ret;
     544                rest -= ret;
     545        }
     546
     547        if (tail_zero)
     548                (void) snprintf(cur, rest, ":");
     549
    433550        return EOK;
    434551}
     
    446563int inet_addr_format(const inet_addr_t *addr, char **bufp)
    447564{
    448         int rc = 0;
    449        
     565        int rc;
     566
     567        rc = ENOTSUP;
     568
    450569        switch (addr->version) {
    451570        case ip_any:
    452571                rc = asprintf(bufp, "none");
     572                if (rc < 0)
     573                        return ENOMEM;
     574                rc = EOK;
    453575                break;
    454576        case ip_v4:
    455                 rc = asprintf(bufp, "%u.%u.%u.%u", (addr->addr >> 24) & 0xff,
    456                     (addr->addr >> 16) & 0xff, (addr->addr >> 8) & 0xff,
    457                     addr->addr & 0xff);
     577                rc = inet_addr_format_v4(addr->addr, bufp);
    458578                break;
    459579        case ip_v6:
    460                 *bufp = (char *) malloc(INET6_ADDRSTRLEN);
    461                 if (*bufp == NULL)
    462                         return ENOMEM;
    463                
    464                 return inet_ntop(AF_INET6, addr->addr6, *bufp, INET6_ADDRSTRLEN);
    465         default:
    466                 return ENOTSUP;
    467         }
    468        
    469         if (rc < 0)
    470                 return ENOMEM;
    471        
    472         return EOK;
     580                rc = inet_addr_format_v6(addr->addr6, bufp);
     581                break;
     582        }
     583
     584        return rc;
    473585}
    474586
     
    485597int inet_naddr_format(const inet_naddr_t *naddr, char **bufp)
    486598{
    487         int rc = 0;
    488         char prefix[INET_PREFIXSTRSIZE];
    489        
     599        int rc;
     600        char *astr;
     601
     602        rc = ENOTSUP;
     603
    490604        switch (naddr->version) {
    491605        case ip_any:
    492606                rc = asprintf(bufp, "none");
     607                if (rc < 0)
     608                        return ENOMEM;
     609                rc = EOK;
    493610                break;
    494611        case ip_v4:
    495                 rc = asprintf(bufp, "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8
    496                     "/%" PRIu8, (naddr->addr >> 24) & 0xff,
    497                     (naddr->addr >> 16) & 0xff, (naddr->addr >> 8) & 0xff,
    498                     naddr->addr & 0xff, naddr->prefix);
    499                 break;
    500         case ip_v6:
    501                 *bufp = (char *) malloc(INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
    502                 if (*bufp == NULL)
     612                rc = inet_addr_format_v4(naddr->addr, &astr);
     613                if (rc != EOK)
    503614                        return ENOMEM;
    504                
    505                 rc = inet_ntop(AF_INET6, naddr->addr6, *bufp,
    506                     INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
    507                 if (rc != EOK) {
    508                         free(*bufp);
    509                         return rc;
    510                 }
    511                
    512                 rc = snprintf(prefix, INET_PREFIXSTRSIZE, "/%" PRIu8,
    513                     naddr->prefix);
     615
     616                rc = asprintf(bufp, "%s/%" PRIu8, astr, naddr->prefix);
    514617                if (rc < 0) {
    515                         free(*bufp);
     618                        free(astr);
    516619                        return ENOMEM;
    517620                }
    518                
    519                 str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix);
    520                
    521                 break;
    522         default:
    523                 return ENOTSUP;
    524         }
    525        
    526         if (rc < 0)
    527                 return ENOMEM;
    528        
    529         return EOK;
     621
     622                rc = EOK;
     623                break;
     624        case ip_v6:
     625                rc = inet_addr_format_v6(naddr->addr6, &astr);
     626                if (rc != EOK)
     627                        return ENOMEM;
     628
     629                rc = asprintf(bufp, "%s/%" PRIu8, astr, naddr->prefix);
     630                if (rc < 0) {
     631                        free(astr);
     632                        return ENOMEM;
     633                }
     634
     635                rc = EOK;
     636                break;
     637        }
     638
     639        return rc;
    530640}
    531641
     
    586696}
    587697
    588 void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr)
    589 {
    590         addr->version = ip_v4;
    591         addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr);
    592 }
    593 
    594698void inet_addr_set6(addr128_t v6, inet_addr_t *addr)
    595699{
     
    605709}
    606710
    607 void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6,
    608     inet_addr_t *addr)
    609 {
    610         addr->version = ip_v6;
    611         addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6);
    612 }
    613 
    614 uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr,
    615     sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6)
    616 {
    617         switch (addr->version) {
    618         case ip_v4:
    619                 if (sockaddr_in != NULL) {
    620                         sockaddr_in->sin_family = AF_INET;
    621                         sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr);
    622                 }
    623                 break;
    624         case ip_v6:
    625                 if (sockaddr_in6 != NULL) {
    626                         sockaddr_in6->sin6_family = AF_INET6;
    627                         host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr);
    628                 }
    629                 break;
    630         default:
    631                 assert(false);
    632                 break;
    633         }
    634 
    635         return ipver_af(addr->version);
    636 }
    637 
    638 int inet_addr_sockaddr(const inet_addr_t *addr, uint16_t port,
    639     sockaddr_t **nsockaddr, socklen_t *naddrlen)
    640 {
    641         sockaddr_in_t *sa4;
    642         sockaddr_in6_t *sa6;
    643 
    644         switch (addr->version) {
    645         case ip_v4:
    646                 sa4 = calloc(1, sizeof(sockaddr_in_t));
    647                 if (sa4 == NULL)
    648                         return ENOMEM;
    649 
    650                 sa4->sin_family = AF_INET;
    651                 sa4->sin_port = host2uint16_t_be(port);
    652                 sa4->sin_addr.s_addr = host2uint32_t_be(addr->addr);
    653                 if (nsockaddr != NULL)
    654                         *nsockaddr = (sockaddr_t *)sa4;
    655                 if (naddrlen != NULL)
    656                         *naddrlen = sizeof(*sa4);
    657                 break;
    658         case ip_v6:
    659                 sa6 = calloc(1, sizeof(sockaddr_in6_t));
    660                 if (sa6 == NULL)
    661                         return ENOMEM;
    662 
    663                 sa6->sin6_family = AF_INET6;
    664                 sa6->sin6_port = host2uint16_t_be(port);
    665                 host2addr128_t_be(addr->addr6, sa6->sin6_addr.s6_addr);
    666                 if (nsockaddr != NULL)
    667                         *nsockaddr = (sockaddr_t *)sa6;
    668                 if (naddrlen != NULL)
    669                         *naddrlen = sizeof(*sa6);
    670                 break;
    671         default:
    672                 assert(false);
    673                 break;
    674         }
    675 
    676         return EOK;
    677 }
    678 
    679711/** @}
    680712 */
  • uspace/lib/c/generic/inet/endpoint.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup socket
     29/** @addtogroup libc
    3030 * @{
    3131 */
    32 
    33 /** @file
    34  * Command-line argument parsing functions related to networking.
     32/** @file Internet endpoint
    3533 */
    3634
    37 extern int socket_parse_address_family(const char *, int *);
    38 extern int socket_parse_protocol_family(const char *, int *);
    39 extern int socket_parse_socket_type(const char *, int *);
     35#include <inet/endpoint.h>
     36#include <mem.h>
     37
     38void inet_ep_init(inet_ep_t *ep)
     39{
     40        memset(ep, 0, sizeof(*ep));
     41}
     42
     43void inet_ep2_init(inet_ep2_t *ep2)
     44{
     45        memset(ep2, 0, sizeof(*ep2));
     46}
    4047
    4148/** @}
  • uspace/lib/c/generic/iplink.c

    r0453261 ree1c2d9  
    4747static void iplink_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    4848
    49 int iplink_open(async_sess_t *sess, iplink_ev_ops_t *ev_ops,
     49int iplink_open(async_sess_t *sess, iplink_ev_ops_t *ev_ops, void *arg,
    5050    iplink_t **riplink)
    5151{
     
    5656        iplink->sess = sess;
    5757        iplink->ev_ops = ev_ops;
     58        iplink->arg = arg;
    5859       
    5960        async_exch_t *exch = async_exchange_begin(sess);
     
    234235       
    235236        return (int) retval;
     237}
     238
     239void *iplink_get_userptr(iplink_t *iplink)
     240{
     241        return iplink->arg;
    236242}
    237243
  • uspace/lib/c/include/errno.h

    r0453261 ree1c2d9  
    6868#define ENAK (-303)
    6969
    70 /** An API function is called while another blocking function is in progress. */
    71 #define EINPROGRESS  (-10036)
    72 
    73 /** The socket identifier is not valid. */
    74 #define ENOTSOCK  (-10038)
    75 
    76 /** The destination address required. */
    77 #define EDESTADDRREQ  (-10039)
    78 
    79 /** Protocol is not supported.  */
    80 #define EPROTONOSUPPORT  (-10043)
    81 
    82 /** Socket type is not supported. */
    83 #define ESOCKTNOSUPPORT  (-10044)
    84 
    85 /** Protocol family is not supported. */
    86 #define EPFNOSUPPORT  (-10046)
    87 
    88 /** Address family is not supported. */
    89 #define EAFNOSUPPORT  (-10047)
    90 
    91 /** Address is already in use. */
    92 #define EADDRINUSE  (-10048)
    93 
    94 /** The socket is not connected or bound. */
    95 #define ENOTCONN  (-10057)
    96 
    97 #define ECONNREFUSED  (-10058)
    98 
    99 #define ECONNABORTED  (-10059)
    100 
    10170/** The requested operation was not performed. Try again later. */
    10271#define EAGAIN  (-11002)
    103 
    104 /** No data. */
    105 #define NO_DATA (-11004)
    10672
    10773#endif
  • uspace/lib/c/include/fibril_synch.h

    r0453261 ree1c2d9  
    135135        fid_t fibril;
    136136        fibril_timer_state_t state;
    137         bool handler_running;
     137        /** FID of fibril executing handler or 0 if handler is not running */
     138        fid_t handler_fid;
    138139
    139140        suseconds_t delay;
  • uspace/lib/c/include/inet/addr.h

    r0453261 ree1c2d9  
    3737
    3838#include <stdint.h>
    39 #include <net/in.h>
    40 #include <net/in6.h>
    41 #include <net/socket.h>
    4239
    4340typedef uint32_t addr32_t;
     
    126123extern void inet_addr_set(addr32_t, inet_addr_t *);
    127124extern void inet_naddr_set(addr32_t, uint8_t, inet_naddr_t *);
    128 extern void inet_sockaddr_in_addr(const sockaddr_in_t *, inet_addr_t *);
    129125
    130126extern void inet_addr_set6(addr128_t, inet_addr_t *);
    131127extern void inet_naddr_set6(addr128_t, uint8_t, inet_naddr_t *);
    132 extern void inet_sockaddr_in6_addr(const sockaddr_in6_t *, inet_addr_t *);
    133 
    134 extern uint16_t inet_addr_sockaddr_in(const inet_addr_t *, sockaddr_in_t *,
    135     sockaddr_in6_t *);
    136 
    137 extern ip_ver_t ipver_from_af(int af);
    138 extern int inet_addr_sockaddr(const inet_addr_t *, uint16_t, sockaddr_t **,
    139     socklen_t *);
    140128
    141129#endif
  • uspace/lib/c/include/inet/endpoint.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2828
    2929/** @addtogroup libc
    30  *  @{
     30 * @{
     31 */
     32/** @file
    3133 */
    3234
    33 /** @file
    34  *  Character string to integer map.
     35#ifndef LIBC_INET_ASSOC_H_
     36#define LIBC_INET_ASSOC_H_
     37
     38#include <stdint.h>
     39#include <inet/addr.h>
     40#include <loc.h>
     41
     42/** Internet port number ranges
     43 *
     44 * Port number ranges per RFC 6335 section 6 (Port Number Ranges.
     45 * Technically port zero is a system port. But since it is reserved,
     46 * we will use it as a special value denoting no port is specified
     47 * and we will exclude it from the system port range to disallow
     48 * ever assigning it.
    3549 */
    36 
    37 #ifndef LIBC_CHAR_MAP_H_
    38 #define LIBC_CHAR_MAP_H_
    39 
    40 #include <libarch/types.h>
    41 
    42 /** Invalid assigned value used also if an&nbsp;entry does not exist. */
    43 #define CHAR_MAP_NULL  (-1)
    44 
    45 /** Type definition of the character string to integer map.
    46  *  @see char_map
    47  */
    48 typedef struct char_map char_map_t;
    49 
    50 /** Character string to integer map item.
    51  *
    52  * This structure recursivelly contains itself as a character by character tree.
    53  * The actually mapped character string consists of all the parent characters
    54  * and the actual one.
    55  */
    56 struct char_map {
    57         /** Actually mapped character. */
    58         uint8_t c;
    59         /** Stored integral value. */
    60         int value;
    61         /** Next character array size. */
    62         int size;
    63         /** First free position in the next character array. */
    64         int next;
    65         /** Next character array. */
    66         char_map_t **items;
    67         /** Consistency check magic value. */
    68         int magic;
     50enum inet_port_ranges {
     51        /** Special value meaning no specific port */
     52        inet_port_any = 0,
     53        /** Lowest system port (a.k.a. well known port) */
     54        inet_port_sys_lo = 1,
     55        /** Highest system port (a.k.a. well known port) */
     56        inet_port_sys_hi = 1023,
     57        /** Lowest user port (a.k.a. registered port) */
     58        inet_port_user_lo = 1024,
     59        /** Highest user port (a.k.a. registered port) */
     60        inet_port_user_hi = 49151,
     61        /** Lowest dynamic port (a.k.a. private or ephemeral port) */
     62        inet_port_dyn_lo = 49152,
     63        /** Highest dynamic port (a.k.a. private or ephemeral port) */
     64        inet_port_dyn_hi = 65535
    6965};
    7066
    71 extern int char_map_initialize(char_map_t *);
    72 extern void char_map_destroy(char_map_t *);
    73 extern int char_map_exclude(char_map_t *, const uint8_t *, size_t);
    74 extern int char_map_add(char_map_t *, const uint8_t *, size_t, const int);
    75 extern int char_map_find(const char_map_t *, const uint8_t *, size_t);
    76 extern int char_map_update(char_map_t *, const uint8_t *, size_t, const int);
     67/** Internet endpoint (address-port pair), a.k.a. socket */
     68typedef struct {
     69        inet_addr_t addr;
     70        uint16_t port;
     71} inet_ep_t;
     72
     73/** Internet endpoint pair */
     74typedef struct {
     75        service_id_t local_link;
     76        inet_ep_t local;
     77        inet_ep_t remote;
     78} inet_ep2_t;
     79
     80extern void inet_ep_init(inet_ep_t *);
     81extern void inet_ep2_init(inet_ep2_t *);
    7782
    7883#endif
  • uspace/lib/c/include/inet/iplink.h

    r0453261 ree1c2d9  
    4444        async_sess_t *sess;
    4545        struct iplink_ev_ops *ev_ops;
     46        void *arg;
    4647} iplink_t;
    4748
     
    8182} iplink_ev_ops_t;
    8283
    83 extern int iplink_open(async_sess_t *, iplink_ev_ops_t *, iplink_t **);
     84extern int iplink_open(async_sess_t *, iplink_ev_ops_t *, void *, iplink_t **);
    8485extern void iplink_close(iplink_t *);
    8586extern int iplink_send(iplink_t *, iplink_sdu_t *);
     
    9091extern int iplink_get_mac48(iplink_t *, addr48_t *);
    9192extern int iplink_set_mac48(iplink_t *, addr48_t);
     93extern void *iplink_get_userptr(iplink_t *);
    9294
    9395#endif
  • uspace/lib/c/include/ipc/services.h

    r0453261 ree1c2d9  
    4949        SERVICE_IRC        = FOURCC('i', 'r', 'c', ' '),
    5050        SERVICE_CLIPBOARD  = FOURCC('c', 'l', 'i', 'p'),
    51         SERVICE_UDP        = FOURCC('u', 'd', 'p', ' '),
    52         SERVICE_TCP        = FOURCC('t', 'c', 'p', ' ')
    5351} services_t;
    5452
     
    6159#define SERVICE_NAME_INETPING6  "net/inetping6"
    6260#define SERVICE_NAME_NETCONF    "net/netconf"
     61#define SERVICE_NAME_UDP        "net/udp"
     62#define SERVICE_NAME_TCP        "net/tcp"
    6363
    6464#endif
  • uspace/lib/c/include/ipc/udp.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2015 Jiri Svobda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libc
    30  *  @{
     29/** @addtogroup libcipc
     30 * @{
     31 */
     32/** @file
    3133 */
    3234
    33 /** @file
    34  * Internet protocol numbers according to the on-line IANA - Assigned Protocol
    35  * numbers:
    36  *
    37  * http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml
    38  */
     35#ifndef LIBC_IPC_UDP_H_
     36#define LIBC_IPC_UDP_H_
    3937
    40 #ifndef LIBC_IP_PROTOCOLS_H_
    41 #define LIBC_IP_PROTOCOLS_H_
     38#include <ipc/common.h>
    4239
    43 /** @name IP protocols definitions */
    44 /*@{*/
     40typedef enum {
     41        UDP_CALLBACK_CREATE = IPC_FIRST_USER_METHOD,
     42        UDP_ASSOC_CREATE,
     43        UDP_ASSOC_DESTROY,
     44        UDP_ASSOC_SEND_MSG,
     45        UDP_RMSG_INFO,
     46        UDP_RMSG_READ,
     47        UDP_RMSG_DISCARD
     48} udp_request_t;
    4549
    46 #define IPPROTO_ICMP    1
    47 #define IPPROTO_TCP     6
    48 #define IPPROTO_UDP     17
    49 #define IPPROTO_ICMPV6  58
    50 
    51 /*@}*/
     50typedef enum {
     51        UDP_EV_DATA = IPC_FIRST_USER_METHOD
     52} udp_event_t;
    5253
    5354#endif
  • uspace/lib/http/include/http/http.h

    r0453261 ree1c2d9  
    3737#define HTTP_HTTP_H_
    3838
    39 #include <net/socket.h>
    4039#include <adt/list.h>
    4140#include <inet/addr.h>
     41#include <inet/tcp.h>
    4242
    4343#include "receive-buffer.h"
     
    4848        inet_addr_t addr;
    4949
    50         bool connected;
    51         int conn_sd;
    52        
     50        tcp_t *tcp;
     51        tcp_conn_t *conn;
     52
    5353        size_t buffer_size;
    5454        receive_buffer_t recv_buffer;
  • uspace/lib/http/src/http.c

    r0453261 ree1c2d9  
    3434 */
    3535
     36#include <errno.h>
    3637#include <stdio.h>
    3738#include <stdlib.h>
     
    3940#include <macros.h>
    4041
    41 #include <net/socket.h>
    4242#include <inet/dnsr.h>
     43#include <inet/tcp.h>
    4344
    4445#include <http/http.h>
     
    4849{
    4950        http_t *http = client_data;
    50         return recv(http->conn_sd, buf, buf_size, 0);
     51        size_t nrecv;
     52        int rc;
     53
     54        rc = tcp_conn_recv_wait(http->conn, buf, buf_size, &nrecv);
     55        if (rc != EOK)
     56                return rc;
     57
     58        return nrecv;
    5159}
    5260
     
    7785int http_connect(http_t *http)
    7886{
    79         if (http->connected)
     87        if (http->conn != NULL)
    8088                return EBUSY;
    8189       
     
    95103        }
    96104       
    97         struct sockaddr *saddr;
    98         socklen_t saddrlen;
     105        inet_ep2_t epp;
    99106       
    100         rc = inet_addr_sockaddr(&http->addr, http->port, &saddr, &saddrlen);
    101         if (rc != EOK) {
    102                 assert(rc == ENOMEM);
    103                 return ENOMEM;
    104         }
     107        inet_ep2_init(&epp);
     108        epp.remote.addr = http->addr;
     109        epp.remote.port = http->port;
    105110       
    106         http->conn_sd = socket(saddr->sa_family, SOCK_STREAM, 0);
    107         if (http->conn_sd < 0)
    108                 return http->conn_sd;
     111        rc = tcp_create(&http->tcp);
     112        if (rc != EOK)
     113                return rc;
    109114       
    110         rc = connect(http->conn_sd, saddr, saddrlen);
    111         free(saddr);
     115        rc = tcp_conn_create(http->tcp, &epp, NULL, NULL, &http->conn);
     116        if (rc != EOK)
     117                return rc;
     118       
     119        rc = tcp_conn_wait_connected(http->conn);
     120        if (rc != EOK)
     121                return rc;
    112122       
    113123        return rc;
     
    116126int http_close(http_t *http)
    117127{
    118         if (!http->connected)
     128        if (http->conn == NULL)
    119129                return EINVAL;
    120130       
    121         return closesocket(http->conn_sd);
     131        tcp_conn_destroy(http->conn);
     132        tcp_destroy(http->tcp);
     133        return EOK;
    122134}
    123135
  • uspace/lib/http/src/request.c

    r0453261 ree1c2d9  
    3434 */
    3535
     36#include <errno.h>
    3637#include <stdio.h>
    3738#include <stdlib.h>
     
    3940#include <macros.h>
    4041
    41 #include <net/socket.h>
     42#include <inet/tcp.h>
    4243
    4344#include <http/http.h>
     
    149150                return rc;
    150151       
    151         rc = send(http->conn_sd, buf, buf_size, 0);
     152        rc = tcp_conn_send(http->conn, buf, buf_size);
    152153        free(buf);
    153154       
  • uspace/lib/nettl/Makefile

    r0453261 ree1c2d9  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2015 Jiri Svoboda
    43# All rights reserved.
    54#
     
    3029USPACE_PREFIX = ../..
    3130EXTRA_CFLAGS = -Iinclude
    32 LIBRARY = libnet
     31LIBRARY = libnettl
    3332
    3433SOURCES = \
    35         tl/socket_core.c
     34        src/amap.c \
     35        src/portrng.c
    3636
    3737include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/nettl/include/nettl/portrng.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup nettest
     29/** @addtogroup libnettl
    3030 * @{
    3131 */
    32 
    33 /** @file
    34  * Networking test support functions.
     32/**
     33 * @file Port range allocator.
    3534 */
    3635
    37 #ifndef NET_TEST_
    38 #define NET_TEST_
     36#ifndef LIBNETTL_PORTRNG_H_
     37#define LIBNETTL_PORTRNG_H_
    3938
    40 #include <net/socket.h>
     39#include <stdbool.h>
     40#include <stdint.h>
    4141
    42 extern void print_mark(unsigned int);
    43 extern int sockets_create(int, int *, unsigned int, uint16_t, sock_type_t);
    44 extern int sockets_close(int, int *, unsigned int);
    45 extern int sockets_connect(int, int *, unsigned int, struct sockaddr *,
    46     socklen_t);
    47 extern int sockets_sendto(int, int *, unsigned int, struct sockaddr *,
    48     socklen_t, char *, size_t, unsigned int, sock_type_t);
    49 extern int sockets_recvfrom(int, int *, unsigned int, struct sockaddr *,
    50     socklen_t *, char *, size_t, unsigned int);
    51 extern int sockets_sendto_recvfrom(int, int *, unsigned int, struct sockaddr *,
    52     socklen_t *, char *, size_t, unsigned int, sock_type_t);
     42/** Allocated port */
     43typedef struct {
     44        /** Link to portrng_t.used */
     45        link_t lprng;
     46        /** Port number */
     47        uint16_t pn;
     48        /** User argument */
     49        void *arg;
     50} portrng_port_t;
     51
     52typedef struct {
     53        list_t used; /* of portrng_port_t */
     54} portrng_t;
     55
     56typedef enum {
     57        pf_allow_system = 0x1
     58} portrng_flags_t;
     59
     60extern int portrng_create(portrng_t **);
     61extern void portrng_destroy(portrng_t *);
     62extern int portrng_alloc(portrng_t *, uint16_t, void *,
     63    portrng_flags_t, uint16_t *);
     64extern int portrng_find_port(portrng_t *, uint16_t, void **);
     65extern void portrng_free_port(portrng_t *, uint16_t);
     66extern bool portrng_empty(portrng_t *);
    5367
    5468#endif
     
    5670/** @}
    5771 */
    58 
  • uspace/lib/posix/include/posix/errno.h

    r0453261 ree1c2d9  
    6969extern int *__posix_errno(void);
    7070
    71 #define __TOP_ERRNO (-NO_DATA)
     71#define __TOP_ERRNO (-EAGAIN)
    7272
    7373enum {
    7474        POSIX_E2BIG = __TOP_ERRNO + 1,
    7575        POSIX_EACCES = __TOP_ERRNO + 2,
    76         POSIX_EADDRINUSE = -EADDRINUSE,
    7776        POSIX_EADDRNOTAVAIL = -EADDRNOTAVAIL,
    78         POSIX_EAFNOSUPPORT = -EAFNOSUPPORT,
    7977        POSIX_EAGAIN = -EAGAIN,
    8078        POSIX_EALREADY = __TOP_ERRNO + 3,
     
    8886        POSIX_ECONNRESET = __TOP_ERRNO + 9,
    8987        POSIX_EDEADLK = __TOP_ERRNO + 10,
    90         POSIX_EDESTADDRREQ = -EDESTADDRREQ,
    9188        POSIX_EDOM = __TOP_ERRNO + 11,
    9289        POSIX_EDQUOT = __TOP_ERRNO + 12,
     
    9794        POSIX_EIDRM = __TOP_ERRNO + 16,
    9895        POSIX_EILSEQ = __TOP_ERRNO + 17,
    99         POSIX_EINPROGRESS = -EINPROGRESS,
    10096        POSIX_EINTR = -EINTR,
    10197        POSIX_EINVAL = -EINVAL,
     
    114110        POSIX_ENFILE = __TOP_ERRNO + 25,
    115111        POSIX_ENOBUFS = __TOP_ERRNO + 26,
    116         POSIX_ENODATA = -NO_DATA,
    117112        POSIX_ENODEV = __TOP_ERRNO + 27,
    118113        POSIX_ENOENT = -ENOENT,
     
    127122        POSIX_ENOSTR = __TOP_ERRNO + 34,
    128123        POSIX_ENOSYS = __TOP_ERRNO + 35,
    129         POSIX_ENOTCONN = -ENOTCONN,
    130124        POSIX_ENOTDIR = -ENOTDIR,
    131125        POSIX_ENOTEMPTY = -ENOTEMPTY,
    132126        POSIX_ENOTRECOVERABLE = __TOP_ERRNO + 36,
    133         POSIX_ENOTSOCK = -ENOTSOCK,
    134127        POSIX_ENOTSUP = -ENOTSUP,
    135128        POSIX_ENOTTY = __TOP_ERRNO + 37,
     
    141134        POSIX_EPIPE = __TOP_ERRNO + 41,
    142135        POSIX_EPROTO = __TOP_ERRNO + 42,
    143         POSIX_EPROTONOSUPPORT = -EPROTONOSUPPORT,
    144136        POSIX_EPROTOTYPE = __TOP_ERRNO + 43,
    145137        POSIX_ERANGE = -ERANGE,
     
    153145        POSIX_EWOULDBLOCK = __TOP_ERRNO + 51,
    154146        POSIX_EXDEV = -EXDEV,
     147        POSIX_EINPROGRESS = __TOP_ERRNO + 52,
     148        POSIX_ENOTSOCK = __TOP_ERRNO + 53,
     149        POSIX_EDESTADDRREQ = __TOP_ERRNO + 54,
     150        POSIX_EPROTONOSUPPORT = __TOP_ERRNO + 55,
     151        POSIX_EAFNOSUPPORT = __TOP_ERRNO + 56,
     152        POSIX_EADDRINUSE = __TOP_ERRNO + 57,
     153        POSIX_ENOTCONN = __TOP_ERRNO + 58,
     154        POSIX_ENODATA = __TOP_ERRNO + 59,
    155155};
    156156
  • uspace/srv/hid/remcons/remcons.c

    r0453261 ree1c2d9  
    4444#include <fibril_synch.h>
    4545#include <task.h>
    46 #include <net/in.h>
    47 #include <net/inet.h>
    48 #include <net/socket.h>
     46#include <inet/addr.h>
     47#include <inet/endpoint.h>
     48#include <inet/tcp.h>
    4949#include <io/console.h>
    5050#include <inttypes.h>
     
    9999};
    100100
     101static void remcons_new_conn(tcp_listener_t *lst, tcp_conn_t *conn);
     102
     103static tcp_listen_cb_t listen_cb = {
     104        .new_conn = remcons_new_conn
     105};
     106
     107static tcp_cb_t conn_cb = {
     108        .connected = NULL
     109};
     110
    101111static telnet_user_t *srv_to_user(con_srv_t *srv)
    102112{
     
    111121
    112122        /* Force character mode. */
    113         send(user->socket, (void *)telnet_force_character_mode_command,
    114             telnet_force_character_mode_command_count, 0);
     123        (void) tcp_conn_send(user->conn, (void *)telnet_force_character_mode_command,
     124            telnet_force_character_mode_command_count);
    115125
    116126        return EOK;
     
    272282}
    273283
    274 /** Fibril for each accepted socket.
    275  *
    276  * @param arg Corresponding @c telnet_user_t structure.
    277  */
    278 static int network_user_fibril(void *arg)
    279 {
    280         telnet_user_t *user = arg;
     284/** Handle network connection.
     285 *
     286 * @param lst  Listener
     287 * @param conn Connection
     288 */
     289static void remcons_new_conn(tcp_listener_t *lst, tcp_conn_t *conn)
     290{
     291        telnet_user_t *user = telnet_user_create(conn);
     292        assert(user);
     293
     294        con_srvs_init(&user->srvs);
     295        user->srvs.ops = &con_ops;
     296        user->srvs.sarg = user;
     297        user->srvs.abort_timeout = 1000;
     298
     299        telnet_user_add(user);
    281300
    282301        int rc = loc_service_register(user->service_name, &user->service_id);
     
    284303                telnet_user_error(user, "Unable to register %s with loc: %s.",
    285304                    user->service_name, str_error(rc));
    286                 return EOK;
     305                return;
    287306        }
    288307
    289308        telnet_user_log(user, "Service %s registerd with id %" PRIun ".",
    290309            user->service_name, user->service_id);
    291        
     310
    292311        fid_t spawn_fibril = fibril_create(spawn_task_fibril, user);
    293312        assert(spawn_fibril);
    294313        fibril_add_ready(spawn_fibril);
    295        
     314
    296315        /* Wait for all clients to exit. */
    297316        fibril_mutex_lock(&user->guard);
    298317        while (!user_can_be_destroyed_no_lock(user)) {
    299318                if (user->task_finished) {
    300                         closesocket(user->socket);
     319                        user->conn = NULL;
    301320                        user->socket_closed = true;
    302321                        user->srvs.aborted = true;
     
    310329        }
    311330        fibril_mutex_unlock(&user->guard);
    312        
     331
    313332        rc = loc_service_unregister(user->service_id);
    314333        if (rc != EOK) {
     
    320339        telnet_user_log(user, "Destroying...");
    321340        telnet_user_destroy(user);
    322 
    323         return EOK;
    324341}
    325342
    326343int main(int argc, char *argv[])
    327344{
    328         int port = 2223;
    329        
     345        int rc;
     346        tcp_listener_t *lst;
     347        tcp_t *tcp;
     348        inet_ep_t ep;
     349
    330350        async_set_client_connection(client_connection);
    331         int rc = loc_server_register(NAME);
     351        rc = loc_server_register(NAME);
    332352        if (rc != EOK) {
    333353                fprintf(stderr, "%s: Unable to register server\n", NAME);
    334354                return rc;
    335355        }
    336        
    337         struct sockaddr_in addr;
    338        
    339         addr.sin_family = AF_INET;
    340         addr.sin_port = htons(port);
    341        
    342         rc = inet_pton(AF_INET, "127.0.0.1", (void *)
    343             &addr.sin_addr.s_addr);
    344         if (rc != EOK) {
    345                 fprintf(stderr, "Error parsing network address: %s.\n",
    346                     str_error(rc));
    347                 return 2;
    348         }
    349 
    350         int listen_sd = socket(PF_INET, SOCK_STREAM, 0);
    351         if (listen_sd < 0) {
    352                 fprintf(stderr, "Error creating listening socket: %s.\n",
    353                     str_error(listen_sd));
    354                 return 3;
    355         }
    356 
    357         rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
    358         if (rc != EOK) {
    359                 fprintf(stderr, "Error binding socket: %s.\n",
    360                     str_error(rc));
    361                 return 4;
    362         }
    363 
    364         rc = listen(listen_sd, BACKLOG_SIZE);
    365         if (rc != EOK) {
    366                 fprintf(stderr, "listen() failed: %s.\n", str_error(rc));
    367                 return 5;
     356
     357        rc = tcp_create(&tcp);
     358        if (rc != EOK) {
     359                fprintf(stderr, "%s: Error initializing TCP.\n", NAME);
     360                return rc;
     361        }
     362
     363        inet_ep_init(&ep);
     364        ep.port = 2223;
     365
     366        rc = tcp_listener_create(tcp, &ep, &listen_cb, NULL, &conn_cb, NULL,
     367            &lst);
     368        if (rc != EOK) {
     369                fprintf(stderr, "%s: Error creating listener.\n", NAME);
     370                return rc;
    368371        }
    369372
    370373        printf("%s: HelenOS Remote console service\n", NAME);
    371374        task_retval(0);
    372 
    373         while (true) {
    374                 struct sockaddr_in raddr;
    375                 socklen_t raddr_len = sizeof(raddr);
    376                 int conn_sd = accept(listen_sd, (struct sockaddr *) &raddr,
    377                     &raddr_len);
    378 
    379                 if (conn_sd < 0) {
    380                         fprintf(stderr, "accept() failed: %s.\n",
    381                             str_error(rc));
    382                         continue;
    383                 }
    384 
    385                 telnet_user_t *user = telnet_user_create(conn_sd);
    386                 assert(user);
    387 
    388                 con_srvs_init(&user->srvs);
    389                 user->srvs.ops = &con_ops;
    390                 user->srvs.sarg = user;
    391                 user->srvs.abort_timeout = 1000;
    392 
    393                 telnet_user_add(user);
    394 
    395                 fid_t fid = fibril_create(network_user_fibril, user);
    396                 assert(fid);
    397                 fibril_add_ready(fid);
    398         }
    399 
     375        async_manager();
     376
     377        /* Not reached */
    400378        return 0;
    401379}
  • uspace/srv/hid/remcons/remcons.h

    r0453261 ree1c2d9  
    3838#define NAME       "remcons"
    3939#define NAMESPACE  "term"
    40 #define BACKLOG_SIZE  5
    4140
    4241#endif
  • uspace/srv/hid/remcons/user.c

    r0453261 ree1c2d9  
    4444#include <fibril_synch.h>
    4545#include <task.h>
    46 #include <net/in.h>
    47 #include <net/inet.h>
    48 #include <net/socket.h>
     46#include <inet/tcp.h>
    4947#include <io/console.h>
    5048#include <inttypes.h>
     
    5856/** Create new telnet user.
    5957 *
    60  * @param socket Socket the user communicates through.
     58 * @param conn Incoming connection.
    6159 * @return New telnet user or NULL when out of memory.
    6260 */
    63 telnet_user_t *telnet_user_create(int socket)
     61telnet_user_t *telnet_user_create(tcp_conn_t *conn)
    6462{
    6563        static int telnet_user_id_counter = 0;
     
    7876        }
    7977
    80         user->socket = socket;
     78        user->conn = conn;
    8179        user->service_id = (service_id_t) -1;
    8280        prodcons_initialize(&user->in_events);
     
    193191        /* No more buffered data? */
    194192        if (user->socket_buffer_len <= user->socket_buffer_pos) {
    195                 int recv_length = recv(user->socket, user->socket_buffer, BUFFER_SIZE, 0);
    196                 if ((recv_length == 0) || (recv_length == ENOTCONN)) {
     193                int rc;
     194                size_t recv_length;
     195
     196                rc = tcp_conn_recv_wait(user->conn, user->socket_buffer,
     197                    BUFFER_SIZE, &recv_length);
     198                if (rc != EOK)
     199                        return rc;
     200
     201                if (recv_length == 0) {
    197202                        user->socket_closed = true;
    198203                        user->srvs.aborted = true;
    199204                        return ENOENT;
    200205                }
    201                 if (recv_length < 0) {
    202                         return recv_length;
    203                 }
     206
    204207                user->socket_buffer_len = recv_length;
    205208                user->socket_buffer_pos = 0;
     
    359362
    360363
    361         int rc = send(user->socket, converted, converted_size, 0);
     364        int rc = tcp_conn_send(user->conn, converted, converted_size);
    362365        free(converted);
    363366
  • uspace/srv/hid/remcons/user.h

    r0453261 ree1c2d9  
    3838#include <adt/prodcons.h>
    3939#include <fibril_synch.h>
     40#include <inet/tcp.h>
    4041#include <inttypes.h>
    4142#include <io/con_srv.h>
     
    5152        /** Internal id, used for creating locfs entries. */
    5253        int id;
    53         /** Associated socket. */
    54         int socket;
     54        /** Associated connection. */
     55        tcp_conn_t *conn;
    5556        /** Location service id assigned to the virtual terminal. */
    5657        service_id_t service_id;
     
    8081} telnet_user_t;
    8182
    82 extern telnet_user_t *telnet_user_create(int);
     83extern telnet_user_t *telnet_user_create(tcp_conn_t *);
    8384extern void telnet_user_add(telnet_user_t *);
    8485extern void telnet_user_destroy(telnet_user_t *);
  • uspace/srv/hid/rfb/main.c

    r0453261 ree1c2d9  
    150150}
    151151
    152 static int socket_fibril(void *unused)
    153 {
    154         rfb_accept(&rfb);
    155        
    156         /* Not reached */
    157         return EOK;
    158 }
    159 
    160152int main(int argc, char **argv)
    161153{
     
    267259        }
    268260       
    269         fid_t fib = fibril_create(socket_fibril, NULL);
    270         if (!fib) {
    271                 fprintf(stderr, NAME ": Unable to create socket fibril.\n");
    272                 return 2;
    273         }
    274        
    275         fibril_add_ready(fib);
    276        
    277261        printf("%s: Accepting connections\n", NAME);
    278262        task_retval(0);
  • uspace/srv/hid/rfb/rfb.c

    r0453261 ree1c2d9  
    3131#include <stdlib.h>
    3232#include <fibril_synch.h>
     33#include <inet/addr.h>
     34#include <inet/endpoint.h>
     35#include <inet/tcp.h>
    3336#include <inttypes.h>
    3437#include <str.h>
     
    3841#include <io/log.h>
    3942
    40 #include <net/in.h>
    41 #include <net/inet.h>
    42 #include <net/socket.h>
    43 
    4443#include "rfb.h"
     44
     45static void rfb_new_conn(tcp_listener_t *, tcp_conn_t *);
     46
     47static tcp_listen_cb_t listen_cb = {
     48        .new_conn = rfb_new_conn
     49};
     50
     51static tcp_cb_t conn_cb = {
     52        .connected = NULL
     53};
    4554
    4655/** Buffer for receiving the request. */
     
    5362
    5463/** Receive one character (with buffering) */
    55 static int recv_char(int fd, char *c)
    56 {
     64static int recv_char(tcp_conn_t *conn, char *c)
     65{
     66        size_t nrecv;
     67        int rc;
     68
    5769        if (rbuf_out == rbuf_in) {
    5870                rbuf_out = 0;
    5971                rbuf_in = 0;
    6072               
    61                 ssize_t rc = recv(fd, rbuf, BUFFER_SIZE, 0);
    62                 if (rc <= 0)
     73                rc = tcp_conn_recv_wait(conn, rbuf, BUFFER_SIZE, &nrecv);
     74                if (rc != EOK)
    6375                        return rc;
    6476               
    65                 rbuf_in = rc;
     77                rbuf_in = nrecv;
    6678        }
    6779       
     
    7183
    7284/** Receive count characters (with buffering) */
    73 static int recv_chars(int fd, char *c, size_t count)
     85static int recv_chars(tcp_conn_t *conn, char *c, size_t count)
    7486{
    7587        for (size_t i = 0; i < count; i++) {
    76                 int rc = recv_char(fd, c);
     88                int rc = recv_char(conn, c);
    7789                if (rc != EOK)
    7890                        return rc;
     
    8294}
    8395
    84 static int recv_skip_chars(int fd, size_t count)
     96static int recv_skip_chars(tcp_conn_t *conn, size_t count)
    8597{
    8698        for (size_t i = 0; i < count; i++) {
    8799                char c;
    88                 int rc = recv_char(fd, &c);
     100                int rc = recv_char(conn, &c);
    89101                if (rc != EOK)
    90102                        return rc;
     
    204216}
    205217
    206 static int recv_message(int conn_sd, char type, void *buf, size_t size)
     218static int recv_message(tcp_conn_t *conn, char type, void *buf, size_t size)
    207219{
    208220        memcpy(buf, &type, 1);
    209         return recv_chars(conn_sd, ((char *) buf) + 1, size -1);
     221        return recv_chars(conn, ((char *) buf) + 1, size -1);
    210222}
    211223
     
    477489}
    478490
    479 static int rfb_send_framebuffer_update(rfb_t *rfb, int conn_sd, bool incremental)
     491static int rfb_send_framebuffer_update(rfb_t *rfb, tcp_conn_t *conn,
     492    bool incremental)
    480493{
    481494        fibril_mutex_lock(&rfb->lock);
     
    540553       
    541554        if (!rfb->pixel_format.true_color) {
    542                 int rc = send(conn_sd, send_palette, send_palette_size, 0);
     555                int rc = tcp_conn_send(conn, send_palette, send_palette_size);
    543556                if (rc != EOK) {
    544557                        free(buf);
     
    547560        }
    548561       
    549         int rc = send(conn_sd, buf, buf_size, 0);
     562        int rc = tcp_conn_send(conn, buf, buf_size);
    550563        free(buf);
    551564       
     
    580593}
    581594
    582 static void rfb_socket_connection(rfb_t *rfb, int conn_sd)
     595static void rfb_socket_connection(rfb_t *rfb, tcp_conn_t *conn)
    583596{
    584597        /* Version handshake */
    585         int rc = send(conn_sd, "RFB 003.008\n", 12, 0);
     598        int rc = tcp_conn_send(conn, "RFB 003.008\n", 12);
    586599        if (rc != EOK) {
    587600                log_msg(LOG_DEFAULT, LVL_WARN, "Failed sending server version %d", rc);
     
    590603       
    591604        char client_version[12];
    592         rc = recv_chars(conn_sd, client_version, 12);
     605        rc = recv_chars(conn, client_version, 12);
    593606        if (rc != EOK) {
    594607                log_msg(LOG_DEFAULT, LVL_WARN, "Failed receiving client version: %d", rc);
     
    607620        sec_types[0] = 1; /* length */
    608621        sec_types[1] = RFB_SECURITY_NONE;
    609         rc = send(conn_sd, sec_types, 2, 0);
     622        rc = tcp_conn_send(conn, sec_types, 2);
    610623        if (rc != EOK) {
    611624                log_msg(LOG_DEFAULT, LVL_WARN,
     
    615628       
    616629        char selected_sec_type = 0;
    617         rc = recv_char(conn_sd, &selected_sec_type);
     630        rc = recv_char(conn, &selected_sec_type);
    618631        if (rc != EOK) {
    619632                log_msg(LOG_DEFAULT, LVL_WARN, "Failed receiving security type: %d", rc);
     
    626639        }
    627640        uint32_t security_result = RFB_SECURITY_HANDSHAKE_OK;
    628         rc = send(conn_sd, &security_result, sizeof(uint32_t), 0);
     641        rc = tcp_conn_send(conn, &security_result, sizeof(uint32_t));
    629642        if (rc != EOK) {
    630643                log_msg(LOG_DEFAULT, LVL_WARN, "Failed sending security result: %d", rc);
     
    634647        /* Client init */
    635648        char shared_flag;
    636         rc = recv_char(conn_sd, &shared_flag);
     649        rc = recv_char(conn, &shared_flag);
    637650        if (rc != EOK) {
    638651                log_msg(LOG_DEFAULT, LVL_WARN, "Failed receiving client init: %d", rc);
     
    657670        memcpy(server_init->name, rfb->name, name_length);
    658671        fibril_mutex_unlock(&rfb->lock);
    659         rc = send(conn_sd, server_init, msg_length, 0);
     672        rc = tcp_conn_send(conn, server_init, msg_length);
    660673        if (rc != EOK) {
    661674                log_msg(LOG_DEFAULT, LVL_WARN, "Failed sending server init: %d", rc);
     
    665678        while (true) {
    666679                char message_type = 0;
    667                 rc = recv_char(conn_sd, &message_type);
     680                rc = recv_char(conn, &message_type);
    668681                if (rc != EOK) {
    669682                        log_msg(LOG_DEFAULT, LVL_WARN,
     
    680693                switch (message_type) {
    681694                case RFB_CMSG_SET_PIXEL_FORMAT:
    682                         recv_message(conn_sd, message_type, &spf, sizeof(spf));
     695                        recv_message(conn, message_type, &spf, sizeof(spf));
    683696                        rfb_pixel_format_to_host(&spf.pixel_format, &spf.pixel_format);
    684697                        log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received SetPixelFormat message");
     
    690703                        break;
    691704                case RFB_CMSG_SET_ENCODINGS:
    692                         recv_message(conn_sd, message_type, &se, sizeof(se));
     705                        recv_message(conn, message_type, &se, sizeof(se));
    693706                        rfb_set_encodings_to_host(&se, &se);
    694707                        log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received SetEncodings message");
    695708                        for (uint16_t i = 0; i < se.count; i++) {
    696709                                int32_t encoding = 0;
    697                                 rc = recv_chars(conn_sd, (char *) &encoding, sizeof(int32_t));
     710                                rc = recv_chars(conn, (char *) &encoding, sizeof(int32_t));
    698711                                if (rc != EOK)
    699712                                        return;
     
    707720                        break;
    708721                case RFB_CMSG_FRAMEBUFFER_UPDATE_REQUEST:
    709                         recv_message(conn_sd, message_type, &fbur, sizeof(fbur));
     722                        recv_message(conn, message_type, &fbur, sizeof(fbur));
    710723                        rfb_framebuffer_update_request_to_host(&fbur, &fbur);
    711724                        log_msg(LOG_DEFAULT, LVL_DEBUG2,
    712725                            "Received FramebufferUpdateRequest message");
    713                         rfb_send_framebuffer_update(rfb, conn_sd, fbur.incremental);
     726                        rfb_send_framebuffer_update(rfb, conn, fbur.incremental);
    714727                        break;
    715728                case RFB_CMSG_KEY_EVENT:
    716                         recv_message(conn_sd, message_type, &ke, sizeof(ke));
     729                        recv_message(conn, message_type, &ke, sizeof(ke));
    717730                        rfb_key_event_to_host(&ke, &ke);
    718731                        log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received KeyEvent message");
    719732                        break;
    720733                case RFB_CMSG_POINTER_EVENT:
    721                         recv_message(conn_sd, message_type, &pe, sizeof(pe));
     734                        recv_message(conn, message_type, &pe, sizeof(pe));
    722735                        rfb_pointer_event_to_host(&pe, &pe);
    723736                        log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received PointerEvent message");
    724737                        break;
    725738                case RFB_CMSG_CLIENT_CUT_TEXT:
    726                         recv_message(conn_sd, message_type, &cct, sizeof(cct));
     739                        recv_message(conn, message_type, &cct, sizeof(cct));
    727740                        rfb_client_cut_text_to_host(&cct, &cct);
    728741                        log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received ClientCutText message");
    729                         recv_skip_chars(conn_sd, cct.length);
     742                        recv_skip_chars(conn, cct.length);
    730743                        break;
    731744                default:
     
    737750}
    738751
    739 int rfb_listen(rfb_t *rfb, uint16_t port) {
    740         struct sockaddr_in addr;
    741        
    742         addr.sin_family = AF_INET;
    743         addr.sin_port = htons(port);
    744        
    745         int rc = inet_pton(AF_INET, "127.0.0.1", (void *)
    746             &addr.sin_addr.s_addr);
    747         if (rc != EOK) {
    748                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error parsing network address (%s)",
    749                     str_error(rc));
    750                 return rc;
    751         }
    752 
    753         int listen_sd = socket(PF_INET, SOCK_STREAM, 0);
    754         if (listen_sd < 0) {
    755                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating listening socket (%s)",
    756                     str_error(listen_sd));
    757                 return rc;
    758         }
    759        
    760         rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
    761         if (rc != EOK) {
    762                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error binding socket (%s)",
    763                     str_error(rc));
    764                 return rc;
    765         }
    766        
    767         rc = listen(listen_sd, 2);
    768         if (rc != EOK) {
    769                 log_msg(LOG_DEFAULT, LVL_ERROR, "listen() failed (%s)", str_error(rc));
    770                 return rc;
    771         }
    772        
    773         rfb->listen_sd = listen_sd;
     752int rfb_listen(rfb_t *rfb, uint16_t port)
     753{
     754        tcp_t *tcp = NULL;
     755        tcp_listener_t *lst = NULL;
     756        inet_ep_t ep;
     757        int rc;
     758       
     759        rc = tcp_create(&tcp);
     760        if (rc != EOK) {
     761                log_msg(LOG_DEFAULT, LVL_ERROR, "Error initializing TCP.");
     762                goto error;
     763        }
     764       
     765        inet_ep_init(&ep);
     766        ep.port = port;
     767       
     768        rc = tcp_listener_create(tcp, &ep, &listen_cb, rfb, &conn_cb, rfb,
     769            &lst);
     770        if (rc != EOK) {
     771                log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating listener.");
     772                goto error;
     773        }
     774       
     775        rfb->tcp = tcp;
     776        rfb->lst = lst;
    774777       
    775778        return EOK;
    776 }
    777 
    778 void rfb_accept(rfb_t *rfb)
    779 {
    780         while (true) {
    781                 struct sockaddr_in raddr;
    782                 socklen_t raddr_len = sizeof(raddr);
    783                 int conn_sd = accept(rfb->listen_sd, (struct sockaddr *) &raddr,
    784                     &raddr_len);
    785                
    786                 if (conn_sd < 0) {
    787                         log_msg(LOG_DEFAULT, LVL_WARN, "accept() failed (%s)",
    788                             str_error(conn_sd));
    789                         continue;
    790                 }
    791                
    792                 log_msg(LOG_DEFAULT, LVL_DEBUG, "Connection accepted");
    793                
    794                 rbuf_out = 0;
    795                 rbuf_in = 0;
    796                
    797                 rfb_socket_connection(rfb, conn_sd);
    798                 closesocket(conn_sd);
    799         }
    800 }
     779error:
     780        tcp_listener_destroy(lst);
     781        tcp_destroy(tcp);
     782        return rc;
     783}
     784
     785static void rfb_new_conn(tcp_listener_t *lst, tcp_conn_t *conn)
     786{
     787        rfb_t *rfb = (rfb_t *)tcp_listener_userptr(lst);
     788        log_msg(LOG_DEFAULT, LVL_DEBUG, "Connection accepted");
     789
     790        rbuf_out = 0;
     791        rbuf_in = 0;
     792
     793        rfb_socket_connection(rfb, conn);
     794}
  • uspace/srv/hid/rfb/rfb.h

    r0453261 ree1c2d9  
    3030#define RFB_H__
    3131
     32#include <inet/tcp.h>
    3233#include <io/pixelmap.h>
    3334#include <fibril_synch.h>
     
    151152        rfb_pixel_format_t pixel_format;
    152153        const char *name;
    153         int listen_sd;
     154        tcp_t *tcp;
     155        tcp_listener_t *lst;
    154156        pixelmap_t framebuffer;
    155157        rfb_rectangle_t damage_rect;
     
    165167extern int rfb_set_size(rfb_t *, uint16_t, uint16_t);
    166168extern int rfb_listen(rfb_t *, uint16_t);
    167 extern void rfb_accept(rfb_t *);
    168169
    169170#endif
  • uspace/srv/net/dhcp/dhcp.c

    r0453261 ree1c2d9  
    3737#include <adt/list.h>
    3838#include <bitops.h>
     39#include <byteorder.h>
    3940#include <errno.h>
    4041#include <fibril_synch.h>
     
    562563        }
    563564
    564         /* XXX Work around multiple simultaneous sessions issue */
    565         dhcp_transport_fini(&dlink->dt);
    566 
    567565        log_msg(LOG_DEFAULT, LVL_NOTE, "%s: Successfully configured.",
    568566            dlink->link_info.name);
  • uspace/srv/net/dhcp/transport.c

    r0453261 ree1c2d9  
    3636
    3737#include <bitops.h>
     38#include <errno.h>
    3839#include <inet/addr.h>
    3940#include <inet/dnsr.h>
     
    4142#include <io/log.h>
    4243#include <loc.h>
    43 #include <net/in.h>
    44 #include <net/inet.h>
    45 #include <net/socket.h>
    4644#include <stdio.h>
    4745#include <stdlib.h>
     
    6765} dhcp_offer_t;
    6866
    69 static int dhcp_recv_fibril(void *);
     67static void dhcp_recv_msg(udp_assoc_t *, udp_rmsg_t *);
     68static void dhcp_recv_err(udp_assoc_t *, udp_rerr_t *);
     69static void dhcp_link_state(udp_assoc_t *, udp_link_state_t);
     70
     71static udp_cb_t dhcp_transport_cb = {
     72        .recv_msg = dhcp_recv_msg,
     73        .recv_err = dhcp_recv_err,
     74        .link_state = dhcp_link_state
     75};
    7076
    7177int dhcp_send(dhcp_transport_t *dt, void *msg, size_t size)
    7278{
    73         struct sockaddr_in addr;
     79        inet_ep_t ep;
    7480        int rc;
    7581
    76         addr.sin_family = AF_INET;
    77         addr.sin_port = htons(dhcp_server_port);
    78         addr.sin_addr.s_addr = htonl(addr32_broadcast_all_hosts);
     82        inet_ep_init(&ep);
     83        ep.port = dhcp_server_port;
     84        inet_addr_set(addr32_broadcast_all_hosts, &ep.addr);
    7985
    80         rc = sendto(dt->fd, msg, size, 0,
    81             (struct sockaddr *)&addr, sizeof(addr));
     86        rc = udp_assoc_send_msg(dt->assoc, &ep, msg, size);
    8287        if (rc != EOK) {
    83                 log_msg(LOG_DEFAULT, LVL_ERROR, "Sending failed");
     88                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed sending message");
    8489                return rc;
    8590        }
     
    8893}
    8994
    90 static int dhcp_recv_msg(dhcp_transport_t *dt, void **rmsg, size_t *rsize)
     95static void dhcp_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg)
    9196{
    92         struct sockaddr_in src_addr;
    93         socklen_t src_addr_size;
    94         size_t recv_size;
     97        dhcp_transport_t *dt;
     98        size_t s;
    9599        int rc;
    96100
    97         if (dt->fd < 0) {
    98                 /* Terminated */
    99                 return EIO;
     101        log_msg(LOG_DEFAULT, LVL_NOTE, "dhcp_recv_msg()");
     102
     103        dt = (dhcp_transport_t *)udp_assoc_userptr(assoc);
     104        s = udp_rmsg_size(rmsg);
     105        if (s > MAX_MSG_SIZE)
     106                s = MAX_MSG_SIZE; /* XXX */
     107
     108        rc = udp_rmsg_read(rmsg, 0, msgbuf, s);
     109        if (rc != EOK) {
     110                log_msg(LOG_DEFAULT, LVL_ERROR, "Error receiving message.");
     111                return;
    100112        }
    101113
    102         src_addr_size = sizeof(src_addr);
    103         rc = recvfrom(dt->fd, msgbuf, MAX_MSG_SIZE, 0,
    104             (struct sockaddr *)&src_addr, &src_addr_size);
    105         if (rc < 0) {
    106                 log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom failed (%d)", rc);
    107                 return rc;
    108         }
     114        log_msg(LOG_DEFAULT, LVL_NOTE, "dhcp_recv_msg() - call recv_cb");
     115        dt->recv_cb(dt->cb_arg, msgbuf, s);
     116}
    109117
    110         recv_size = (size_t)rc;
    111         *rmsg = msgbuf;
    112         *rsize = recv_size;
     118static void dhcp_recv_err(udp_assoc_t *assoc, udp_rerr_t *rerr)
     119{
     120        log_msg(LOG_DEFAULT, LVL_WARN, "Ignoring ICMP error");
     121}
    113122
    114         return EOK;
     123static void dhcp_link_state(udp_assoc_t *assoc, udp_link_state_t ls)
     124{
     125        log_msg(LOG_DEFAULT, LVL_NOTE, "Link state change");
    115126}
    116127
     
    118129    dhcp_recv_cb_t recv_cb, void *arg)
    119130{
    120         int fd;
    121         struct sockaddr_in laddr;
    122         int fid;
     131        udp_t *udp = NULL;
     132        udp_assoc_t *assoc = NULL;
     133        inet_ep2_t epp;
    123134        int rc;
    124135
    125         log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcptransport_init()");
     136        log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_transport_init()");
    126137
    127         laddr.sin_family = AF_INET;
    128         laddr.sin_port = htons(dhcp_client_port);
    129         laddr.sin_addr.s_addr = INADDR_ANY;
     138        inet_ep2_init(&epp);
     139        epp.local.addr.version = ip_v4;
     140        epp.local.port = dhcp_client_port;
     141        epp.local_link = link_id;
    130142
    131         fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    132         if (fd < 0) {
    133                 rc = EIO;
    134                 goto error;
    135         }
    136 
    137         log_msg(LOG_DEFAULT, LVL_DEBUG, "Bind socket.");
    138         rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
     143        rc = udp_create(&udp);
    139144        if (rc != EOK) {
    140145                rc = EIO;
     
    142147        }
    143148
    144         log_msg(LOG_DEFAULT, LVL_DEBUG, "Set socket options");
    145         rc = setsockopt(fd, SOL_SOCKET, SO_IPLINK, &link_id, sizeof(link_id));
     149        rc = udp_assoc_create(udp, &epp, &dhcp_transport_cb, dt, &assoc);
    146150        if (rc != EOK) {
    147151                rc = EIO;
     
    149153        }
    150154
    151         dt->fd = fd;
     155        dt->udp = udp;
     156        dt->assoc = assoc;
    152157        dt->recv_cb = recv_cb;
    153158        dt->cb_arg = arg;
    154159
    155         fid = fibril_create(dhcp_recv_fibril, dt);
    156         if (fid == 0) {
    157                 rc = ENOMEM;
    158                 goto error;
    159         }
    160 
    161         dt->recv_fid = fid;
    162         fibril_add_ready(fid);
    163 
    164160        return EOK;
    165161error:
    166         closesocket(fd);
     162        udp_assoc_destroy(assoc);
     163        udp_destroy(udp);
    167164        return rc;
    168165}
     
    170167void dhcp_transport_fini(dhcp_transport_t *dt)
    171168{
    172         closesocket(dt->fd);
    173         dt->fd = -1;
    174 }
    175 
    176 static int dhcp_recv_fibril(void *arg)
    177 {
    178         dhcp_transport_t *dt = (dhcp_transport_t *)arg;
    179         void *msg;
    180         size_t size = (size_t) -1;
    181         int rc;
    182 
    183         while (true) {
    184                 rc = dhcp_recv_msg(dt, &msg, &size);
    185                 if (rc != EOK)
    186                         break;
    187 
    188                 assert(size != (size_t) -1);
    189 
    190                 dt->recv_cb(dt->cb_arg, msg, size);
    191         }
    192 
    193         return EOK;
     169        udp_assoc_destroy(dt->assoc);
     170        udp_destroy(dt->udp);
    194171}
    195172
  • uspace/srv/net/dhcp/transport.h

    r0453261 ree1c2d9  
    3838#define TRANSPORT_H
    3939
     40#include <inet/udp.h>
    4041#include <ipc/loc.h>
    4142#include <sys/types.h>
     
    4748
    4849struct dhcp_transport {
    49         /** Transport socket */
    50         int fd;
     50        /** UDP */
     51        udp_t *udp;
     52        /** UDP association */
     53        udp_assoc_t *assoc;
    5154        /** Receive callback */
    5255        dhcp_recv_cb_t recv_cb;
    5356        /** Callback argument */
    5457        void *cb_arg;
    55         /** Receive fibril ID */
    56         int recv_fid;
    5758};
    5859
  • uspace/srv/net/dnsrsrv/transport.c

    r0453261 ree1c2d9  
    3737#include <errno.h>
    3838#include <fibril_synch.h>
     39#include <inet/addr.h>
     40#include <inet/endpoint.h>
     41#include <inet/udp.h>
    3942#include <io/log.h>
    40 #include <net/in.h>
    41 #include <net/inet.h>
    42 #include <net/socket.h>
    4343#include <stdbool.h>
    4444#include <stdlib.h>
     
    7272
    7373static uint8_t recv_buf[RECV_BUF_SIZE];
    74 static fid_t recv_fid;
    75 static int transport_fd = -1;
     74static udp_t *transport_udp;
     75static udp_assoc_t *transport_assoc;
    7676
    7777/** Outstanding requests */
     
    7979static FIBRIL_MUTEX_INITIALIZE(treq_lock);
    8080
    81 static int transport_recv_fibril(void *arg);
     81static void transport_recv_msg(udp_assoc_t *, udp_rmsg_t *);
     82static void transport_recv_err(udp_assoc_t *, udp_rerr_t *);
     83static void transport_link_state(udp_assoc_t *, udp_link_state_t);
     84
     85static udp_cb_t transport_cb = {
     86        .recv_msg = transport_recv_msg,
     87        .recv_err = transport_recv_err,
     88        .link_state = transport_link_state
     89};
    8290
    8391int transport_init(void)
    8492{
    85         struct sockaddr_in laddr;
    86         int fd;
    87         fid_t fid;
     93        inet_ep2_t epp;
    8894        int rc;
    8995
    90         laddr.sin_family = AF_INET;
    91         laddr.sin_port = htons(12345);
    92         laddr.sin_addr.s_addr = INADDR_ANY;
    93 
    94         fd = -1;
    95 
    96         fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    97         if (fd < 0) {
     96        inet_ep2_init(&epp);
     97
     98        rc = udp_create(&transport_udp);
     99        if (rc != EOK) {
    98100                rc = EIO;
    99101                goto error;
    100102        }
    101103
    102         rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
    103         if (rc != EOK)
    104                 goto error;
    105 
    106         transport_fd = fd;
    107 
    108         fid = fibril_create(transport_recv_fibril, NULL);
    109         if (fid == 0)
    110                 goto error;
    111 
    112         fibril_add_ready(fid);
    113         recv_fid = fid;
     104        rc = udp_assoc_create(transport_udp, &epp, &transport_cb, NULL,
     105            &transport_assoc);
     106        if (rc != EOK) {
     107                rc = EIO;
     108                goto error;
     109        }
     110
    114111        return EOK;
    115112error:
    116         log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network socket.");
    117         if (fd >= 0)
    118                 closesocket(fd);
     113        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network.");
     114        udp_assoc_destroy(transport_assoc);
     115        udp_destroy(transport_udp);
    119116        return rc;
    120117}
     
    122119void transport_fini(void)
    123120{
    124         if (transport_fd >= 0)
    125                 closesocket(transport_fd);
     121        udp_assoc_destroy(transport_assoc);
     122        udp_destroy(transport_udp);
    126123}
    127124
     
    182179{
    183180        trans_req_t *treq = NULL;
    184         struct sockaddr *saddr = NULL;
    185         socklen_t saddrlen;
    186        
     181        inet_ep_t ep;
     182
    187183        void *req_data;
    188184        size_t req_size;
     
    190186        if (rc != EOK)
    191187                goto error;
    192        
    193         rc = inet_addr_sockaddr(&dns_server_addr, DNS_SERVER_PORT,
    194             &saddr, &saddrlen);
    195         if (rc != EOK) {
    196                 assert(rc == ENOMEM);
    197                 goto error;
    198         }
    199        
     188
     189        inet_ep_init(&ep);
     190        ep.addr = dns_server_addr;
     191        ep.port = DNS_SERVER_PORT;
     192
    200193        size_t ntry = 0;
    201        
     194
    202195        while (ntry < REQ_RETRY_MAX) {
    203                 rc = sendto(transport_fd, req_data, req_size, 0,
    204                     saddr, saddrlen);
     196                rc = udp_assoc_send_msg(transport_assoc, &ep, req_data,
     197                    req_size);
    205198                if (rc != EOK)
    206199                        goto error;
    207                
     200
    208201                treq = treq_create(req);
    209202                if (treq == NULL) {
     
    211204                        goto error;
    212205                }
    213                
     206
    214207                fibril_mutex_lock(&treq->done_lock);
    215208                while (treq->done != true) {
     
    221214                        }
    222215                }
    223                
     216
    224217                fibril_mutex_unlock(&treq->done_lock);
    225                
     218
    226219                if (rc != ETIMEOUT)
    227220                        break;
    228221        }
    229        
     222
    230223        if (ntry >= REQ_RETRY_MAX) {
    231224                rc = EIO;
    232225                goto error;
    233226        }
    234        
     227
    235228        if (treq->status != EOK) {
    236229                rc = treq->status;
    237230                goto error;
    238231        }
    239        
     232
    240233        *rresp = treq->resp;
    241234        treq_destroy(treq);
    242235        free(req_data);
    243         free(saddr);
    244236        return EOK;
    245        
     237
    246238error:
    247239        if (treq != NULL)
    248240                treq_destroy(treq);
    249        
     241
    250242        free(req_data);
    251         free(saddr);
    252243        return rc;
    253244}
    254245
    255 static int transport_recv_msg(dns_message_t **rresp)
    256 {
    257         struct sockaddr_in src_addr;
    258         socklen_t src_addr_size;
    259         size_t recv_size;
    260         dns_message_t *resp;
    261         int rc;
    262 
    263         src_addr_size = sizeof(src_addr);
    264         rc = recvfrom(transport_fd, recv_buf, RECV_BUF_SIZE, 0,
    265             (struct sockaddr *)&src_addr, &src_addr_size);
    266         if (rc < 0) {
    267                 log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom returns error - %d", rc);
    268                 goto error;
    269         }
    270 
    271         recv_size = (size_t)rc;
    272 
    273         rc = dns_message_decode(recv_buf, recv_size, &resp);
    274         if (rc != EOK) {
    275                 rc = EIO;
    276                 goto error;
    277         }
    278 
    279         *rresp = resp;
    280         return EOK;
    281 
    282 error:
    283         return rc;
    284 }
    285 
    286 static int transport_recv_fibril(void *arg)
     246static void transport_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg)
    287247{
    288248        dns_message_t *resp = NULL;
    289249        trans_req_t *treq;
     250        size_t size;
     251        inet_ep_t remote_ep;
    290252        int rc;
    291253
    292         while (true) {
    293                 rc = transport_recv_msg(&resp);
    294                 if (rc != EOK)
    295                         continue;
    296 
    297                 assert(resp != NULL);
    298 
    299                 fibril_mutex_lock(&treq_lock);
    300                 treq = treq_match_resp(resp);
    301                 if (treq == NULL) {
    302                         fibril_mutex_unlock(&treq_lock);
    303                         continue;
    304                 }
    305 
    306                 list_remove(&treq->lreq);
     254        size = udp_rmsg_size(rmsg);
     255        if (size > RECV_BUF_SIZE)
     256                size = RECV_BUF_SIZE; /* XXX */
     257
     258        rc = udp_rmsg_read(rmsg, 0, recv_buf, size);
     259        if (rc != EOK) {
     260                log_msg(LOG_DEFAULT, LVL_ERROR, "Error reading message.");
     261                return;
     262        }
     263
     264        udp_rmsg_remote_ep(rmsg, &remote_ep);
     265        /* XXX */
     266
     267        rc = dns_message_decode(recv_buf, size, &resp);
     268        if (rc != EOK) {
     269                log_msg(LOG_DEFAULT, LVL_ERROR, "Error decoding message.");
     270                return;
     271        }
     272
     273        assert(resp != NULL);
     274
     275        fibril_mutex_lock(&treq_lock);
     276        treq = treq_match_resp(resp);
     277        if (treq == NULL) {
    307278                fibril_mutex_unlock(&treq_lock);
    308 
    309                 treq_complete(treq, resp);
    310         }
    311 
    312         return 0;
    313 }
     279                return;
     280        }
     281
     282        list_remove(&treq->lreq);
     283        fibril_mutex_unlock(&treq_lock);
     284
     285        treq_complete(treq, resp);
     286}
     287
     288static void transport_recv_err(udp_assoc_t *assoc, udp_rerr_t *rerr)
     289{
     290        log_msg(LOG_DEFAULT, LVL_WARN, "Ignoring ICMP error");
     291}
     292
     293static void transport_link_state(udp_assoc_t *assoc, udp_link_state_t ls)
     294{
     295        log_msg(LOG_DEFAULT, LVL_NOTE, "Link state change");
     296}
     297
    314298
    315299/** @}
  • uspace/srv/net/inetsrv/inet_link.c

    r0453261 ree1c2d9  
    7373{
    7474        memcpy(ip_addr, link_local_node_ip, 16);
    75        
     75
    7676        ip_addr[8] = mac_addr[0] ^ 0x02;
    7777        ip_addr[9] = mac_addr[1];
     
    8585{
    8686        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()");
    87        
     87
    8888        int rc;
    8989        inet_packet_t packet;
    90        
     90        inet_link_t *ilink;
     91
     92        ilink = (inet_link_t *)iplink_get_userptr(iplink);
     93
    9194        switch (ver) {
    9295        case ip_v4:
    93                 rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
     96                rc = inet_pdu_decode(sdu->data, sdu->size, ilink->svc_id,
     97                    &packet);
    9498                break;
    9599        case ip_v6:
    96                 rc = inet_pdu_decode6(sdu->data, sdu->size, &packet);
     100                rc = inet_pdu_decode6(sdu->data, sdu->size, ilink->svc_id,
     101                    &packet);
    97102                break;
    98103        default:
     
    100105                return EINVAL;
    101106        }
    102        
     107
    103108        if (rc != EOK) {
    104109                log_msg(LOG_DEFAULT, LVL_DEBUG, "failed decoding PDU");
    105110                return rc;
    106111        }
    107        
     112
     113        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_iplink_recv: link_id=%zu", packet.link_id);
    108114        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()");
    109115        rc = inet_recv_packet(&packet);
    110116        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet -> %d", rc);
    111117        free(packet.data);
    112        
     118
    113119        return rc;
    114120}
     
    177183        }
    178184
    179         rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, &ilink->iplink);
     185        rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, ilink, &ilink->iplink);
    180186        if (rc != EOK) {
    181187                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed opening IP link '%s'",
  • uspace/srv/net/inetsrv/inetsrv.c

    r0453261 ree1c2d9  
    469469{
    470470        async_exch_t *exch = async_exchange_begin(client->sess);
    471        
     471
    472472        ipc_call_t answer;
    473         aid_t req = async_send_1(exch, INET_EV_RECV, dgram->tos, &answer);
    474        
     473
     474        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_ev_recv: iplink=%zu",
     475            dgram->iplink);
     476
     477        aid_t req = async_send_2(exch, INET_EV_RECV, dgram->tos,
     478            dgram->iplink, &answer);
     479
    475480        int rc = async_data_write_start(exch, &dgram->src, sizeof(inet_addr_t));
    476481        if (rc != EOK) {
     
    479484                return rc;
    480485        }
    481        
     486
    482487        rc = async_data_write_start(exch, &dgram->dest, sizeof(inet_addr_t));
    483488        if (rc != EOK) {
     
    486491                return rc;
    487492        }
    488        
     493
    489494        rc = async_data_write_start(exch, dgram->data, dgram->size);
    490        
     495
    491496        async_exchange_end(exch);
    492        
     497
    493498        if (rc != EOK) {
    494499                async_forget(req);
    495500                return rc;
    496501        }
    497        
     502
    498503        sysarg_t retval;
    499504        async_wait_for(req, &retval);
    500        
     505
    501506        return (int) retval;
    502507}
     
    511516        if (proto == IP_PROTO_ICMP)
    512517                return icmp_recv(dgram);
    513        
     518
    514519        if (proto == IP_PROTO_ICMPV6)
    515520                return icmpv6_recv(dgram);
     
    540545                if (packet->offs == 0 && !packet->mf) {
    541546                        /* It is complete deliver it immediately */
     547                        dgram.iplink = packet->link_id;
    542548                        dgram.src = packet->src;
    543549                        dgram.dest = packet->dest;
  • uspace/srv/net/inetsrv/inetsrv.h

    r0453261 ree1c2d9  
    7575
    7676typedef struct {
     77        /** Local link ID */
     78        service_id_t link_id;
    7779        /** Source address */
    7880        inet_addr_t src;
  • uspace/srv/net/inetsrv/pdu.c

    r0453261 ree1c2d9  
    298298/** Decode IPv4 datagram
    299299 *
    300  * @param data   Serialized IPv4 datagram
    301  * @param size   Length of serialized IPv4 datagram
    302  * @param packet IP datagram structure to be filled
     300 * @param data    Serialized IPv4 datagram
     301 * @param size    Length of serialized IPv4 datagram
     302 * @param link_id Link on which PDU was received
     303 * @param packet  IP datagram structure to be filled
    303304 *
    304305 * @return EOK on success
     
    307308 *
    308309 */
    309 int inet_pdu_decode(void *data, size_t size, inet_packet_t *packet)
     310int inet_pdu_decode(void *data, size_t size, service_id_t link_id,
     311    inet_packet_t *packet)
    310312{
    311313        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_pdu_decode()");
     
    366368       
    367369        memcpy(packet->data, (uint8_t *) data + data_offs, packet->size);
     370        packet->link_id = link_id;
    368371       
    369372        return EOK;
     
    372375/** Decode IPv6 datagram
    373376 *
    374  * @param data   Serialized IPv6 datagram
    375  * @param size   Length of serialized IPv6 datagram
    376  * @param packet IP datagram structure to be filled
     377 * @param data    Serialized IPv6 datagram
     378 * @param size    Length of serialized IPv6 datagram
     379 * @param link_id Link on which PDU was received
     380 * @param packet  IP datagram structure to be filled
    377381 *
    378382 * @return EOK on success
     
    381385 *
    382386 */
    383 int inet_pdu_decode6(void *data, size_t size, inet_packet_t *packet)
     387int inet_pdu_decode6(void *data, size_t size, service_id_t link_id,
     388    inet_packet_t *packet)
    384389{
    385390        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_pdu_decode6()");
     
    457462       
    458463        memcpy(packet->data, (uint8_t *) data + data_offs, packet->size);
    459        
     464        packet->link_id = link_id;
    460465        return EOK;
    461466}
  • uspace/srv/net/inetsrv/pdu.h

    r0453261 ree1c2d9  
    3838#define INET_PDU_H_
    3939
     40#include <loc.h>
    4041#include <sys/types.h>
    4142#include "inetsrv.h"
     
    5051extern int inet_pdu_encode6(inet_packet_t *, addr128_t, addr128_t, size_t,
    5152    size_t, void **, size_t *, size_t *);
    52 extern int inet_pdu_decode(void *, size_t, inet_packet_t *);
    53 extern int inet_pdu_decode6(void *, size_t, inet_packet_t *);
     53extern int inet_pdu_decode(void *, size_t, service_id_t, inet_packet_t *);
     54extern int inet_pdu_decode6(void *, size_t, service_id_t, inet_packet_t *);
    5455
    5556extern int ndp_pdu_decode(inet_dgram_t *, ndp_packet_t *);
  • uspace/srv/net/inetsrv/reass.c

    r0453261 ree1c2d9  
    325325                return ENOMEM;
    326326
     327        /* XXX What if different fragments came from different link? */
     328        dgram.iplink = frag->packet.link_id;
    327329        dgram.size = dgram_size;
    328330        dgram.src = frag->packet.src;
  • uspace/srv/net/tcp/Makefile

    r0453261 ree1c2d9  
    2828
    2929USPACE_PREFIX = ../../..
    30 LIBS = $(LIBNET_PREFIX)/libnet.a
    31 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
     30
     31LIBS = \
     32        $(LIBNETTL_PREFIX)/libnettl.a
     33
     34EXTRA_CFLAGS += \
     35        -I$(LIBNETTL_PREFIX)/include
     36
    3237BINARY = tcp
    3338
     
    3944        rqueue.c \
    4045        segment.c \
     46        service.c \
    4147        seq_no.c \
    42         sock.c \
    4348        tcp.c \
    4449        test.c \
  • uspace/srv/net/tcp/conn.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636
    3737#include <adt/list.h>
    38 #include <stdbool.h>
    3938#include <errno.h>
     39#include <inet/endpoint.h>
    4040#include <io/log.h>
    4141#include <macros.h>
     42#include <nettl/amap.h>
     43#include <stdbool.h>
    4244#include <stdlib.h>
    4345#include "conn.h"
     
    5557#define TIME_WAIT_TIMEOUT       (2*MAX_SEGMENT_LIFETIME)
    5658
    57 LIST_INITIALIZE(conn_list);
    58 FIBRIL_MUTEX_INITIALIZE(conn_list_lock);
     59static LIST_INITIALIZE(conn_list);
     60/** Taken after tcp_conn_t lock */
     61static FIBRIL_MUTEX_INITIALIZE(conn_list_lock);
     62static amap_t *amap;
    5963
    6064static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg);
     
    6266static void tcp_conn_tw_timer_clear(tcp_conn_t *conn);
    6367
     68/** Initialize connections. */
     69int tcp_conns_init(void)
     70{
     71        int rc;
     72
     73        rc = amap_create(&amap);
     74        if (rc != EOK) {
     75                assert(rc == ENOMEM);
     76                return ENOMEM;
     77        }
     78
     79        return EOK;
     80}
     81
    6482/** Create new connection structure.
    6583 *
    66  * @param lsock         Local socket (will be deeply copied)
    67  * @param fsock         Foreign socket (will be deeply copied)
     84 * @param epp           Endpoint pair (will be deeply copied)
    6885 * @return              New connection or NULL
    6986 */
    70 tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock)
     87tcp_conn_t *tcp_conn_new(inet_ep2_t *epp)
    7188{
    7289        tcp_conn_t *conn = NULL;
     
    121138        fibril_condvar_initialize(&conn->cstate_cv);
    122139
    123         conn->cstate_cb = NULL;
     140        conn->cb = NULL;
    124141
    125142        conn->cstate = st_listen;
     
    128145        conn->ap = ap_passive;
    129146        conn->fin_is_acked = false;
    130         conn->ident.local = *lsock;
    131         if (fsock != NULL)
    132                 conn->ident.foreign = *fsock;
     147        if (epp != NULL)
     148                conn->ident = *epp;
    133149
    134150        return conn;
     
    184200void tcp_conn_addref(tcp_conn_t *conn)
    185201{
    186         log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_addref(%p)", conn->name, conn);
     202        log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_addref(%p) before=%zu",
     203            conn->name, conn, atomic_get(&conn->refcnt));
    187204        atomic_inc(&conn->refcnt);
    188205}
     
    196213void tcp_conn_delref(tcp_conn_t *conn)
    197214{
    198         log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_delref(%p)", conn->name, conn);
     215        log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_delref(%p) before=%zu",
     216            conn->name, conn, atomic_get(&conn->refcnt));
    199217
    200218        if (atomic_predec(&conn->refcnt) == 0)
     
    237255
    238256        assert(conn->deleted == false);
     257        conn->deleted = true;
     258        conn->cb = NULL;
     259        conn->cb_arg = NULL;
    239260        tcp_conn_delref(conn);
    240261}
     
    244265 * Add connection to the connection map.
    245266 */
    246 void tcp_conn_add(tcp_conn_t *conn)
    247 {
     267int tcp_conn_add(tcp_conn_t *conn)
     268{
     269        inet_ep2_t aepp;
     270        int rc;
     271
    248272        tcp_conn_addref(conn);
    249273        fibril_mutex_lock(&conn_list_lock);
     274
     275        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_add: conn=%p", conn);
     276
     277        rc = amap_insert(amap, &conn->ident, conn, af_allow_system, &aepp);
     278        if (rc != EOK) {
     279                tcp_conn_delref(conn);
     280                fibril_mutex_unlock(&conn_list_lock);
     281                return rc;
     282        }
     283
     284        conn->ident = aepp;
    250285        list_append(&conn->link, &conn_list);
    251286        fibril_mutex_unlock(&conn_list_lock);
     287
     288        return EOK;
    252289}
    253290
     
    259296{
    260297        fibril_mutex_lock(&conn_list_lock);
     298        amap_remove(amap, &conn->ident);
    261299        list_remove(&conn->link);
    262300        fibril_mutex_unlock(&conn_list_lock);
     
    275313
    276314        /* Run user callback function */
    277         if (conn->cstate_cb != NULL) {
     315        if (conn->cb != NULL && conn->cb->cstate_change != NULL) {
    278316                log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_state_set() - run user CB");
    279                 conn->cstate_cb(conn, conn->cstate_cb_arg);
     317                conn->cb->cstate_change(conn, conn->cb_arg, old_state);
    280318        } else {
    281319                log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_state_set() - no user CB");
     
    284322        assert(old_state != st_closed);
    285323        if (nstate == st_closed) {
     324                tcp_conn_remove(conn);
    286325                /* Drop one reference for now being in closed state */
    287326                tcp_conn_delref(conn);
     
    332371}
    333372
    334 /** Match socket with pattern. */
    335 static bool tcp_socket_match(tcp_sock_t *sock, tcp_sock_t *patt)
    336 {
    337         log_msg(LOG_DEFAULT, LVL_DEBUG2,
    338             "tcp_socket_match(sock=(%u), pat=(%u))", sock->port, patt->port);
    339        
    340         if ((!inet_addr_is_any(&patt->addr)) &&
    341             (!inet_addr_compare(&patt->addr, &sock->addr)))
    342                 return false;
    343 
    344         if ((patt->port != TCP_PORT_ANY) &&
    345             (patt->port != sock->port))
    346                 return false;
    347 
    348         log_msg(LOG_DEFAULT, LVL_DEBUG2, " -> match");
    349 
    350         return true;
    351 }
    352 
    353 /** Match socket pair with pattern. */
    354 static bool tcp_sockpair_match(tcp_sockpair_t *sp, tcp_sockpair_t *pattern)
    355 {
    356         log_msg(LOG_DEFAULT, LVL_DEBUG2, "tcp_sockpair_match(%p, %p)", sp, pattern);
    357 
    358         if (!tcp_socket_match(&sp->local, &pattern->local))
    359                 return false;
    360 
    361         if (!tcp_socket_match(&sp->foreign, &pattern->foreign))
    362                 return false;
    363 
    364         return true;
    365 }
    366 
    367 /** Find connection structure for specified socket pair.
    368  *
    369  * A connection is uniquely identified by a socket pair. Look up our
    370  * connection map and return connection structure based on socket pair.
     373/** Find connection structure for specified endpoint pair.
     374 *
     375 * A connection is uniquely identified by a endpoint pair. Look up our
     376 * connection map and return connection structure based on endpoint pair.
    371377 * The connection reference count is bumped by one.
    372378 *
    373  * @param sp    Socket pair
     379 * @param epp   Endpoint pair
    374380 * @return      Connection structure or NULL if not found.
    375381 */
    376 tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp)
    377 {
    378         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref(%p)", sp);
    379        
    380         log_msg(LOG_DEFAULT, LVL_DEBUG2, "compare conn (f:(%u), l:(%u))",
    381             sp->foreign.port, sp->local.port);
    382        
     382tcp_conn_t *tcp_conn_find_ref(inet_ep2_t *epp)
     383{
     384        int rc;
     385        void *arg;
     386        tcp_conn_t *conn;
     387
     388        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref(%p)", epp);
     389
    383390        fibril_mutex_lock(&conn_list_lock);
    384        
    385         list_foreach(conn_list, link, tcp_conn_t, conn) {
    386                 tcp_sockpair_t *csp = &conn->ident;
    387                
    388                 log_msg(LOG_DEFAULT, LVL_DEBUG2, " - with (f:(%u), l:(%u))",
    389                     csp->foreign.port, csp->local.port);
    390                
    391                 if (tcp_sockpair_match(sp, csp)) {
    392                         tcp_conn_addref(conn);
    393                         fibril_mutex_unlock(&conn_list_lock);
    394                         return conn;
    395                 }
    396         }
    397        
     391
     392        rc = amap_find_match(amap, epp, &arg);
     393        if (rc != EOK) {
     394                assert(rc == ENOENT);
     395                fibril_mutex_unlock(&conn_list_lock);
     396                return NULL;
     397        }
     398
     399        conn = (tcp_conn_t *)arg;
     400        tcp_conn_addref(conn);
     401
    398402        fibril_mutex_unlock(&conn_list_lock);
    399         return NULL;
     403        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref: got conn=%p",
     404            conn);
     405        return conn;
    400406}
    401407
     
    407413{
    408414        log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_reset()", conn->name);
     415        conn->reset = true;
    409416        tcp_conn_state_set(conn, st_closed);
    410         conn->reset = true;
    411417
    412418        tcp_conn_tw_timer_clear(conn);
     
    877883        if (conn->fin_is_acked) {
    878884                log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN acked -> Closed", conn->name);
    879                 tcp_conn_remove(conn);
    880885                tcp_conn_state_set(conn, st_closed);
    881886                return cp_done;
     
    10061011
    10071012        /* Signal to the receive function that new data has arrived */
    1008         fibril_condvar_broadcast(&conn->rcv_buf_cv);
     1013        if (xfer_size > 0) {
     1014                fibril_condvar_broadcast(&conn->rcv_buf_cv);
     1015                if (conn->cb != NULL && conn->cb->recv_data != NULL)
     1016                        conn->cb->recv_data(conn, conn->cb_arg);
     1017        }
    10091018
    10101019        log_msg(LOG_DEFAULT, LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
     
    10981107                conn->rcv_buf_fin = true;
    10991108                fibril_condvar_broadcast(&conn->rcv_buf_cv);
     1109                if (conn->cb != NULL && conn->cb->recv_data != NULL)
     1110                        conn->cb->recv_data(conn, conn->cb_arg);
    11001111
    11011112                tcp_segment_delete(seg);
     
    11681179 *
    11691180 * @param conn          Connection
    1170  * @param seg           Segment
    1171  */
    1172 void tcp_conn_segment_arrived(tcp_conn_t *conn, tcp_segment_t *seg)
    1173 {
     1181 * @param epp           Endpoint pair on which segment was received
     1182 * @param seg           Segment
     1183 */
     1184void tcp_conn_segment_arrived(tcp_conn_t *conn, inet_ep2_t *epp,
     1185    tcp_segment_t *seg)
     1186{
     1187        inet_ep2_t aepp;
     1188        inet_ep2_t oldepp;
     1189        int rc;
     1190
    11741191        log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_segment_arrived(%p)",
    11751192            conn->name, seg);
    11761193
     1194        tcp_conn_lock(conn);
     1195
     1196        if (conn->cstate == st_closed) {
     1197                log_msg(LOG_DEFAULT, LVL_WARN, "Connection is closed.");
     1198                tcp_unexpected_segment(epp, seg);
     1199                tcp_conn_unlock(conn);
     1200                return;
     1201        }
     1202
     1203        if (inet_addr_is_any(&conn->ident.remote.addr) ||
     1204            conn->ident.remote.port == inet_port_any ||
     1205            inet_addr_is_any(&conn->ident.local.addr)) {
     1206
     1207                log_msg(LOG_DEFAULT, LVL_DEBUG2, "tcp_conn_segment_arrived: "
     1208                    "Changing connection ID, updating amap.");
     1209                oldepp = conn->ident;
     1210
     1211                /* Need to remove and re-insert connection with new identity */
     1212                fibril_mutex_lock(&conn_list_lock);
     1213
     1214                if (inet_addr_is_any(&conn->ident.remote.addr))
     1215                        conn->ident.remote.addr = epp->remote.addr;
     1216
     1217                if (conn->ident.remote.port == inet_port_any)
     1218                        conn->ident.remote.port = epp->remote.port;
     1219
     1220                if (inet_addr_is_any(&conn->ident.local.addr))
     1221                        conn->ident.local.addr = epp->local.addr;
     1222
     1223                rc = amap_insert(amap, &conn->ident, conn, af_allow_system, &aepp);
     1224                if (rc != EOK) {
     1225                        assert(rc != EEXISTS);
     1226                        assert(rc == ENOMEM);
     1227                        log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory.");
     1228                        fibril_mutex_unlock(&conn_list_lock);
     1229                        tcp_conn_unlock(conn);
     1230                        return;
     1231                }
     1232
     1233                amap_remove(amap, &oldepp);
     1234                fibril_mutex_unlock(&conn_list_lock);
     1235
     1236                conn->name = (char *) "a";
     1237        }
     1238
    11771239        switch (conn->cstate) {
    11781240        case st_listen:
    1179                 tcp_conn_sa_listen(conn, seg); break;
     1241                tcp_conn_sa_listen(conn, seg);
     1242                break;
    11801243        case st_syn_sent:
    1181                 tcp_conn_sa_syn_sent(conn, seg); break;
     1244                tcp_conn_sa_syn_sent(conn, seg);
     1245                break;
    11821246        case st_syn_received:
    11831247        case st_established:
     
    11891253        case st_time_wait:
    11901254                /* Process segments in order of sequence number */
    1191                 tcp_conn_sa_queue(conn, seg); break;
     1255                tcp_conn_sa_queue(conn, seg);
     1256                break;
    11921257        case st_closed:
    11931258                log_msg(LOG_DEFAULT, LVL_DEBUG, "state=%d", (int) conn->cstate);
    11941259                assert(false);
    11951260        }
     1261
     1262        tcp_conn_unlock(conn);
    11961263}
    11971264
     
    12161283
    12171284        log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: TW Timeout -> Closed", conn->name);
    1218         tcp_conn_remove(conn);
    12191285        tcp_conn_state_set(conn, st_closed);
    12201286
     
    12631329}
    12641330
    1265 /** Handle unexpected segment received on a socket pair.
     1331/** Handle unexpected segment received on an endpoint pair.
    12661332 *
    12671333 * We reply with an RST unless the received segment has RST.
    12681334 *
    1269  * @param sp            Socket pair which received the segment
     1335 * @param sp            Endpoint pair which received the segment
    12701336 * @param seg           Unexpected segment
    12711337 */
    1272 void tcp_unexpected_segment(tcp_sockpair_t *sp, tcp_segment_t *seg)
    1273 {
    1274         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_unexpected_segment(%p, %p)", sp, seg);
     1338void tcp_unexpected_segment(inet_ep2_t *epp, tcp_segment_t *seg)
     1339{
     1340        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_unexpected_segment(%p, %p)", epp,
     1341            seg);
    12751342
    12761343        if ((seg->ctrl & CTL_RST) == 0)
    1277                 tcp_reply_rst(sp, seg);
    1278 }
    1279 
    1280 /** Compute flipped socket pair for response.
    1281  *
    1282  * Flipped socket pair has local and foreign sockets exchanged.
    1283  *
    1284  * @param sp            Socket pair
    1285  * @param fsp           Place to store flipped socket pair
    1286  */
    1287 void tcp_sockpair_flipped(tcp_sockpair_t *sp, tcp_sockpair_t *fsp)
    1288 {
    1289         fsp->local = sp->foreign;
    1290         fsp->foreign = sp->local;
     1344                tcp_reply_rst(epp, seg);
     1345}
     1346
     1347/** Compute flipped endpoint pair for response.
     1348 *
     1349 * Flipped endpoint pair has local and remote endpoints exchanged.
     1350 *
     1351 * @param epp           Endpoint pair
     1352 * @param fepp          Place to store flipped endpoint pair
     1353 */
     1354void tcp_ep2_flipped(inet_ep2_t *epp, inet_ep2_t *fepp)
     1355{
     1356        fepp->local = epp->remote;
     1357        fepp->remote = epp->local;
    12911358}
    12921359
    12931360/** Send RST in response to an incoming segment.
    12941361 *
    1295  * @param sp            Socket pair which received the segment
     1362 * @param epp           Endpoint pair which received the segment
    12961363 * @param seg           Incoming segment
    12971364 */
    1298 void tcp_reply_rst(tcp_sockpair_t *sp, tcp_segment_t *seg)
     1365void tcp_reply_rst(inet_ep2_t *epp, tcp_segment_t *seg)
    12991366{
    13001367        tcp_segment_t *rseg;
    13011368
    1302         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_reply_rst(%p, %p)", sp, seg);
     1369        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_reply_rst(%p, %p)", epp, seg);
    13031370
    13041371        rseg = tcp_segment_make_rst(seg);
    1305         tcp_transmit_segment(sp, rseg);
     1372        tcp_transmit_segment(epp, rseg);
    13061373}
    13071374
  • uspace/srv/net/tcp/conn.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636#define CONN_H
    3737
     38#include <inet/endpoint.h>
    3839#include <stdbool.h>
    3940#include "tcp_type.h"
    4041
    41 extern tcp_conn_t *tcp_conn_new(tcp_sock_t *, tcp_sock_t *);
     42extern int tcp_conns_init(void);
     43extern tcp_conn_t *tcp_conn_new(inet_ep2_t *);
    4244extern void tcp_conn_delete(tcp_conn_t *);
    43 extern void tcp_conn_add(tcp_conn_t *);
     45extern int tcp_conn_add(tcp_conn_t *);
    4446extern void tcp_conn_remove(tcp_conn_t *);
    4547extern void tcp_conn_reset(tcp_conn_t *conn);
     
    4749extern void tcp_conn_fin_sent(tcp_conn_t *);
    4850extern void tcp_conn_ack_of_fin_rcvd(tcp_conn_t *);
    49 extern tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *);
     51extern tcp_conn_t *tcp_conn_find_ref(inet_ep2_t *);
    5052extern void tcp_conn_addref(tcp_conn_t *);
    5153extern void tcp_conn_delref(tcp_conn_t *);
     
    5355extern void tcp_conn_unlock(tcp_conn_t *);
    5456extern bool tcp_conn_got_syn(tcp_conn_t *);
    55 extern void tcp_conn_segment_arrived(tcp_conn_t *, tcp_segment_t *);
     57extern void tcp_conn_segment_arrived(tcp_conn_t *, inet_ep2_t *,
     58    tcp_segment_t *);
    5659extern void tcp_conn_trim_seg_to_wnd(tcp_conn_t *, tcp_segment_t *);
    57 extern void tcp_unexpected_segment(tcp_sockpair_t *, tcp_segment_t *);
    58 extern void tcp_sockpair_flipped(tcp_sockpair_t *, tcp_sockpair_t *);
    59 extern void tcp_reply_rst(tcp_sockpair_t *, tcp_segment_t *);
     60extern void tcp_unexpected_segment(inet_ep2_t *, tcp_segment_t *);
     61extern void tcp_ep2_flipped(inet_ep2_t *, inet_ep2_t *);
     62extern void tcp_reply_rst(inet_ep2_t *, tcp_segment_t *);
    6063
    6164#endif
  • uspace/srv/net/tcp/ncsim.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4242#include <async.h>
    4343#include <errno.h>
     44#include <inet/endpoint.h>
    4445#include <io/log.h>
    4546#include <stdlib.h>
     
    6566/** Bounce segment through simulator into receive queue.
    6667 *
    67  * @param sp    Socket pair, oriented for transmission
     68 * @param epp   Endpoint pair, oriented for transmission
    6869 * @param seg   Segment
    6970 */
    70 void tcp_ncsim_bounce_seg(tcp_sockpair_t *sp, tcp_segment_t *seg)
     71void tcp_ncsim_bounce_seg(inet_ep2_t *epp, tcp_segment_t *seg)
    7172{
    7273        tcp_squeue_entry_t *sqe;
     
    7576
    7677        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ncsim_bounce_seg()");
    77         tcp_rqueue_bounce_seg(sp, seg);
     78        tcp_rqueue_bounce_seg(epp, seg);
    7879        return;
    7980
     
    9293
    9394        sqe->delay = random() % (1000 * 1000);
    94         sqe->sp = *sp;
     95        sqe->epp = *epp;
    9596        sqe->seg = seg;
    9697
     
    147148
    148149                log_msg(LOG_DEFAULT, LVL_DEBUG, "NCSim - End Sleep");
    149                 tcp_rqueue_bounce_seg(&sqe->sp, sqe->seg);
     150                tcp_rqueue_bounce_seg(&sqe->epp, sqe->seg);
    150151                free(sqe);
    151152        }
  • uspace/srv/net/tcp/ncsim.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636#define NCSIM_H
    3737
     38#include <inet/endpoint.h>
    3839#include "tcp_type.h"
    3940
    4041extern void tcp_ncsim_init(void);
    41 extern void tcp_ncsim_bounce_seg(tcp_sockpair_t *, tcp_segment_t *);
     42extern void tcp_ncsim_bounce_seg(inet_ep2_t *, tcp_segment_t *);
    4243extern void tcp_ncsim_fibril_start(void);
    4344
  • uspace/srv/net/tcp/pdu.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#include <byteorder.h>
    3939#include <errno.h>
     40#include <inet/endpoint.h>
    4041#include <mem.h>
    4142#include <stdlib.h>
     
    125126}
    126127
    127 static void tcp_header_setup(tcp_sockpair_t *sp, tcp_segment_t *seg, tcp_header_t *hdr)
     128static void tcp_header_setup(inet_ep2_t *epp, tcp_segment_t *seg, tcp_header_t *hdr)
    128129{
    129130        uint16_t doff_flags;
    130131        uint16_t doff;
    131132
    132         hdr->src_port = host2uint16_t_be(sp->local.port);
    133         hdr->dest_port = host2uint16_t_be(sp->foreign.port);
     133        hdr->src_port = host2uint16_t_be(epp->local.port);
     134        hdr->dest_port = host2uint16_t_be(epp->remote.port);
    134135        hdr->seq = host2uint32_t_be(seg->seq);
    135136        hdr->ack = host2uint32_t_be(seg->ack);
     
    190191}
    191192
    192 static int tcp_header_encode(tcp_sockpair_t *sp, tcp_segment_t *seg,
     193static int tcp_header_encode(inet_ep2_t *epp, tcp_segment_t *seg,
    193194    void **header, size_t *size)
    194195{
     
    199200                return ENOMEM;
    200201
    201         tcp_header_setup(sp, seg, hdr);
     202        tcp_header_setup(epp, seg, hdr);
    202203        *header = hdr;
    203204        *size = sizeof(tcp_header_t);
     
    293294
    294295/** Decode incoming PDU */
    295 int tcp_pdu_decode(tcp_pdu_t *pdu, tcp_sockpair_t *sp, tcp_segment_t **seg)
     296int tcp_pdu_decode(tcp_pdu_t *pdu, inet_ep2_t *epp, tcp_segment_t **seg)
    296297{
    297298        tcp_segment_t *nseg;
     
    307308        hdr = (tcp_header_t *)pdu->header;
    308309
    309         sp->local.port = uint16_t_be2host(hdr->dest_port);
    310         sp->local.addr = pdu->dest;
    311         sp->foreign.port = uint16_t_be2host(hdr->src_port);
    312         sp->foreign.addr = pdu->src;
     310        epp->local.port = uint16_t_be2host(hdr->dest_port);
     311        epp->local.addr = pdu->dest;
     312        epp->remote.port = uint16_t_be2host(hdr->src_port);
     313        epp->remote.addr = pdu->src;
    313314
    314315        *seg = nseg;
     
    317318
    318319/** Encode outgoing PDU */
    319 int tcp_pdu_encode(tcp_sockpair_t *sp, tcp_segment_t *seg, tcp_pdu_t **pdu)
     320int tcp_pdu_encode(inet_ep2_t *epp, tcp_segment_t *seg, tcp_pdu_t **pdu)
    320321{
    321322        tcp_pdu_t *npdu;
     
    327328                return ENOMEM;
    328329
    329         npdu->src = sp->local.addr;
    330         npdu->dest = sp->foreign.addr;
    331         tcp_header_encode(sp, seg, &npdu->header, &npdu->header_size);
     330        npdu->src = epp->local.addr;
     331        npdu->dest = epp->remote.addr;
     332        tcp_header_encode(epp, seg, &npdu->header, &npdu->header_size);
    332333
    333334        text_size = tcp_segment_text_size(seg);
  • uspace/srv/net/tcp/pdu.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636#define PDU_H
    3737
     38#include <inet/endpoint.h>
    3839#include <sys/types.h>
    3940#include "std.h"
     
    4243extern tcp_pdu_t *tcp_pdu_create(void *, size_t, void *, size_t);
    4344extern void tcp_pdu_delete(tcp_pdu_t *);
    44 extern int tcp_pdu_decode(tcp_pdu_t *, tcp_sockpair_t *, tcp_segment_t **);
    45 extern int tcp_pdu_encode(tcp_sockpair_t *, tcp_segment_t *, tcp_pdu_t **);
     45extern int tcp_pdu_decode(tcp_pdu_t *, inet_ep2_t *, tcp_segment_t **);
     46extern int tcp_pdu_encode(inet_ep2_t *, tcp_segment_t *, tcp_pdu_t **);
    4647
    4748#endif
  • uspace/srv/net/tcp/rqueue.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6767 * This is for testing purposes only.
    6868 *
    69  * @param sp    Socket pair, oriented for transmission
     69 * @param sp    Endpoint pair, oriented for transmission
    7070 * @param seg   Segment
    7171 */
    72 void tcp_rqueue_bounce_seg(tcp_sockpair_t *sp, tcp_segment_t *seg)
     72void tcp_rqueue_bounce_seg(inet_ep2_t *epp, tcp_segment_t *seg)
    7373{
    74         tcp_sockpair_t rident;
     74        inet_ep2_t rident;
    7575
    7676        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_rqueue_bounce_seg()");
     
    8080        tcp_segment_t *dseg;
    8181
    82         if (tcp_pdu_encode(sp, seg, &pdu) != EOK) {
     82        if (tcp_pdu_encode(epp, seg, &pdu) != EOK) {
    8383                log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
    8484                return;
     
    9797#else
    9898        /* Reverse the identification */
    99         tcp_sockpair_flipped(sp, &rident);
     99        tcp_ep2_flipped(epp, &rident);
    100100
    101101        /* Insert segment back into rqueue */
     
    106106/** Insert segment into receive queue.
    107107 *
    108  * @param sp    Socket pair, oriented for reception
     108 * @param epp   Endpoint pair, oriented for reception
    109109 * @param seg   Segment
    110110 */
    111 void tcp_rqueue_insert_seg(tcp_sockpair_t *sp, tcp_segment_t *seg)
     111void tcp_rqueue_insert_seg(inet_ep2_t *epp, tcp_segment_t *seg)
    112112{
    113113        tcp_rqueue_entry_t *rqe;
     
    122122        }
    123123
    124         rqe->sp = *sp;
     124        rqe->epp = *epp;
    125125        rqe->seg = seg;
    126126
     
    140140                rqe = list_get_instance(link, tcp_rqueue_entry_t, link);
    141141
    142                 tcp_as_segment_arrived(&rqe->sp, rqe->seg);
     142                tcp_as_segment_arrived(&rqe->epp, rqe->seg);
    143143                free(rqe);
    144144        }
  • uspace/srv/net/tcp/rqueue.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636#define RQUEUE_H
    3737
     38#include <inet/endpoint.h>
    3839#include "tcp_type.h"
    3940
    4041extern void tcp_rqueue_init(void);
    41 extern void tcp_rqueue_bounce_seg(tcp_sockpair_t *, tcp_segment_t *);
    42 extern void tcp_rqueue_insert_seg(tcp_sockpair_t *, tcp_segment_t *);
     42extern void tcp_rqueue_bounce_seg(inet_ep2_t *, tcp_segment_t *);
     43extern void tcp_rqueue_insert_seg(inet_ep2_t *, tcp_segment_t *);
    4344extern void tcp_rqueue_handler(void *);
    4445extern void tcp_rqueue_fibril_start(void);
  • uspace/srv/net/tcp/service.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3030 * @{
    3131 */
    32 /** @file Socket provider
     32/** @file HelenOS service implementation
    3333 */
    3434
    35 #ifndef SOCK_H
    36 #define SOCK_H
     35#ifndef SERVICE_H
     36#define SERVICE_H
    3737
    38 #include <async.h>
    39 
    40 extern int tcp_sock_init(void);
     38extern int tcp_service_init(void);
    4139
    4240#endif
  • uspace/srv/net/tcp/tcp.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4242#include <io/log.h>
    4343#include <stdio.h>
     44#include <stdlib.h>
    4445#include <task.h>
    4546
     47#include "conn.h"
    4648#include "ncsim.h"
    4749#include "pdu.h"
    4850#include "rqueue.h"
    49 #include "sock.h"
     51#include "service.h"
    5052#include "std.h"
    5153#include "tcp.h"
     
    159161{
    160162        tcp_segment_t *dseg;
    161         tcp_sockpair_t rident;
     163        inet_ep2_t rident;
    162164
    163165        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_received_pdu()");
     
    178180        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_init()");
    179181
     182        rc = tcp_conns_init();
     183        if (rc != EOK) {
     184                assert(rc == ENOMEM);
     185                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing connections");
     186                return ENOMEM;
     187        }
     188
    180189        tcp_rqueue_init();
    181190        tcp_rqueue_fibril_start();
     
    192201        }
    193202
    194         rc = tcp_sock_init();
    195         if (rc != EOK) {
    196                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing socket service.");
     203        rc = tcp_service_init();
     204        if (rc != EOK) {
     205                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing service.");
    197206                return ENOENT;
    198207        }
  • uspace/srv/net/tcp/tcp_type.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include <fibril.h>
    4242#include <fibril_synch.h>
    43 #include <socket_core.h>
    4443#include <sys/types.h>
    4544#include <inet/addr.h>
     45#include <inet/endpoint.h>
    4646
    4747struct tcp_conn;
     
    9090        /* Connection reset */
    9191        TCP_ERESET,
    92         /* Foreign socket unspecified */
     92        /* Remote endpoint unspecified */
    9393        TCP_EUNSPEC,
    9494        /* Insufficient resources */
     
    9797        TCP_EINVPREC,
    9898        /* Security/compartment not allowed */
    99         TCP_EINVCOMP
     99        TCP_EINVCOMP,
     100        TCP_EAGAIN
    100101} tcp_error_t;
    101102
     
    112113} tcp_control_t;
    113114
    114 typedef struct {
    115         inet_addr_t addr;
    116         uint16_t port;
    117 } tcp_sock_t;
    118 
    119 enum tcp_port {
    120         TCP_PORT_ANY = 0
    121 };
    122 
    123 typedef struct {
    124         tcp_sock_t local;
    125         tcp_sock_t foreign;
    126 } tcp_sockpair_t;
    127 
    128115/** Connection incoming segments queue */
    129116typedef struct {
     
    155142typedef void (*tcp_cstate_cb_t)(tcp_conn_t *, void *);
    156143
     144/** Connection callbacks */
     145typedef struct {
     146        void (*cstate_change)(tcp_conn_t *, void *, tcp_cstate_t);
     147        void (*recv_data)(tcp_conn_t *, void *);
     148} tcp_cb_t;
     149
    157150/** Connection */
    158151struct tcp_conn {
     
    160153        link_t link;
    161154
    162         /** Connection state change callback function */
    163         tcp_cstate_cb_t cstate_cb;
     155        /** Connection callbacks function */
     156        tcp_cb_t *cb;
    164157        /** Argument to @c cstate_cb */
    165         void *cstate_cb_arg;
    166 
    167         /** Connection identification (local and foreign socket) */
    168         tcp_sockpair_t ident;
     158        void *cb_arg;
     159
     160        /** Connection identification (local and remote endpoint) */
     161        inet_ep2_t ident;
    169162
    170163        /** Active or passive connection */
     
    274267typedef struct {
    275268        link_t link;
    276         tcp_sockpair_t sp;
     269        inet_ep2_t epp;
    277270        tcp_segment_t *seg;
    278271} tcp_rqueue_entry_t;
     
    282275        link_t link;
    283276        suseconds_t delay;
    284         tcp_sockpair_t sp;
     277        inet_ep2_t epp;
    285278        tcp_segment_t *seg;
    286279} tcp_squeue_entry_t;
     
    319312} tcp_pdu_t;
    320313
    321 typedef struct {
    322         async_sess_t *sess;
    323         socket_cores_t sockets;
    324 } tcp_client_t;
    325 
    326 #define TCP_SOCK_FRAGMENT_SIZE 1024
    327 
    328 typedef struct tcp_sockdata {
    329         /** Lock */
    330         fibril_mutex_t lock;
    331         /** Socket core */
    332         socket_core_t *sock_core;
    333         /** Client */
    334         tcp_client_t *client;
     314/** TCP client connection */
     315typedef struct tcp_cconn {
    335316        /** Connection */
    336317        tcp_conn_t *conn;
    337         /** Local address */
    338         inet_addr_t laddr;
    339         /** Backlog size */
    340         int backlog;
    341         /** Array of listening connections, @c backlog elements */
    342         struct tcp_sock_lconn **lconn;
    343         /** List of connections (from lconn) that are ready to be accepted */
    344         list_t ready;
    345         /** Receiving fibril */
    346         fid_t recv_fibril;
    347         uint8_t recv_buffer[TCP_SOCK_FRAGMENT_SIZE];
    348         size_t recv_buffer_used;
    349         fibril_mutex_t recv_buffer_lock;
    350         fibril_condvar_t recv_buffer_cv;
    351         tcp_error_t recv_error;
    352 } tcp_sockdata_t;
    353 
    354 typedef struct tcp_sock_lconn {
     318        /** Connection ID for the client */
     319        sysarg_t id;
     320        /** Client */
     321        struct tcp_client *client;
     322        link_t lclient;
     323} tcp_cconn_t;
     324
     325/** TCP client listener */
     326typedef struct tcp_clst {
     327        /** Local endpoint */
     328        inet_ep_t elocal;
     329        /** Connection */
    355330        tcp_conn_t *conn;
    356         tcp_sockdata_t *socket;
    357         int index;
    358         link_t ready_list;
    359 } tcp_sock_lconn_t;
    360 
     331        /** Listener ID for the client */
     332        sysarg_t id;
     333        /** Client */
     334        struct tcp_client *client;
     335        /** Link to tcp_client_t.clst */
     336        link_t lclient;
     337} tcp_clst_t;
     338
     339/** TCP client */
     340typedef struct tcp_client {
     341        /** Client callbac session */
     342        async_sess_t *sess;
     343        /** Client's connections */
     344        list_t cconn; /* of tcp_cconn_t */
     345        /** Client's listeners */
     346        list_t clst;
     347} tcp_client_t;
    361348
    362349#endif
  • uspace/srv/net/tcp/test.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5050{
    5151        tcp_conn_t *conn;
    52         tcp_sock_t lsock;
    53         tcp_sock_t fsock;
     52        inet_ep2_t epp;
    5453        char rcv_buf[RCV_BUF_SIZE + 1];
    5554        size_t rcvd;
     
    5756
    5857        printf("test_srv()\n");
    59        
    60         inet_addr(&lsock.addr, 127, 0, 0, 1);
    61         lsock.port = 80;
    62        
    63         inet_addr(&fsock.addr, 127, 0, 0, 1);
    64         fsock.port = 1024;
    65        
     58
     59        inet_ep2_init(&epp);
     60
     61        inet_addr(&epp.local.addr, 127, 0, 0, 1);
     62        epp.local.port = 80;
     63
     64        inet_addr(&epp.remote.addr, 127, 0, 0, 1);
     65        epp.remote.port = 1024;
     66
    6667        printf("S: User open...\n");
    67         tcp_uc_open(&lsock, &fsock, ap_passive, 0, &conn);
     68        tcp_uc_open(&epp, ap_passive, 0, &conn);
    6869        conn->name = (char *) "S";
    6970
     
    9394{
    9495        tcp_conn_t *conn;
    95         tcp_sock_t lsock;
    96         tcp_sock_t fsock;
     96        inet_ep2_t epp;
    9797        const char *msg = "Hello World!";
    9898
    9999        printf("test_cli()\n");
    100        
    101         inet_addr(&lsock.addr, 127, 0, 0, 1);
    102         lsock.port = 1024;
    103        
    104         inet_addr(&fsock.addr, 127, 0, 0, 1);
    105         fsock.port = 80;
     100
     101        inet_ep2_init(&epp);
     102
     103        inet_addr(&epp.local.addr, 127, 0, 0, 1);
     104        epp.local.port = 1024;
     105
     106        inet_addr(&epp.remote.addr, 127, 0, 0, 1);
     107        epp.remote.port = 80;
    106108
    107109        async_usleep(1000*1000*3);
    108110        printf("C: User open...\n");
    109         tcp_uc_open(&lsock, &fsock, ap_active, 0, &conn);
     111        tcp_uc_open(&epp, ap_active, 0, &conn);
    110112        conn->name = (char *) "C";
    111113
  • uspace/srv/net/tcp/tqueue.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    282282}
    283283
    284 void tcp_transmit_segment(tcp_sockpair_t *sp, tcp_segment_t *seg)
     284void tcp_transmit_segment(inet_ep2_t *epp, tcp_segment_t *seg)
    285285{
    286286        log_msg(LOG_DEFAULT, LVL_DEBUG,
    287             "tcp_transmit_segment(f:(%u),l:(%u), %p)",
    288             sp->local.port, sp->foreign.port, seg);
    289        
     287            "tcp_transmit_segment(l:(%u),f:(%u), %p)",
     288            epp->local.port, epp->remote.port, seg);
     289
    290290        log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
    291291            seg->seq, seg->wnd);
     
    301301        tcp_pdu_t *pdu;
    302302
    303         if (tcp_pdu_encode(sp, seg, &pdu) != EOK) {
     303        if (tcp_pdu_encode(epp, seg, &pdu) != EOK) {
    304304                log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
    305305                return;
     
    351351
    352352        /* Reset retransmission timer */
    353         tcp_tqueue_timer_set(tqe->conn);
     353        fibril_timer_set_locked(conn->retransmit.timer, RETRANSMIT_TIMEOUT,
     354            retransmit_timeout_func, (void *) conn);
    354355
    355356        tcp_conn_unlock(conn);
    356         tcp_conn_delref(conn);
    357357
    358358        log_msg(LOG_DEFAULT, LVL_DEBUG, "### %s: retransmit_timeout_func(%p) end", conn->name, conn);
  • uspace/srv/net/tcp/tqueue.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636#define TQUEUE_H
    3737
     38#include <inet/endpoint.h>
    3839#include "std.h"
    3940#include "tcp_type.h"
     
    4849extern void tcp_prepare_transmit_segment(tcp_conn_t *, tcp_segment_t *);
    4950extern void tcp_conn_transmit_segment(tcp_conn_t *, tcp_segment_t *);
    50 extern void tcp_transmit_segment(tcp_sockpair_t *, tcp_segment_t *);
     51extern void tcp_transmit_segment(inet_ep2_t *, tcp_segment_t *);
    5152extern void tcp_header_setup(tcp_conn_t *, tcp_segment_t *, tcp_header_t *);
    5253extern void tcp_phdr_setup(tcp_conn_t *, tcp_segment_t *, tcp_phdr_t *);
  • uspace/srv/net/tcp/ucall.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3535 */
    3636
     37#include <errno.h>
    3738#include <fibril_synch.h>
    3839#include <io/log.h>
     
    5051/** OPEN user call
    5152 *
    52  * @param lsock         Local socket
    53  * @param fsock         Foreign socket
     53 * @param epp           Endpoint pair
    5454 * @param acpass        Active/passive
    5555 * @param oflags        Open flags
     
    6565 * establishment.
    6666 */
    67 tcp_error_t tcp_uc_open(tcp_sock_t *lsock, tcp_sock_t *fsock, acpass_t acpass,
     67tcp_error_t tcp_uc_open(inet_ep2_t *epp, acpass_t acpass,
    6868    tcp_open_flags_t oflags, tcp_conn_t **conn)
    6969{
    7070        tcp_conn_t *nconn;
    71 
    72         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open(%p, %p, %s, %s, %p)",
    73             lsock, fsock, acpass == ap_active ? "active" : "passive",
     71        int rc;
     72
     73        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open(%p, %s, %s, %p)",
     74            epp, acpass == ap_active ? "active" : "passive",
    7475            oflags == tcp_open_nonblock ? "nonblock" : "none", conn);
    7576
    76         nconn = tcp_conn_new(lsock, fsock);
    77         tcp_conn_add(nconn);
     77        nconn = tcp_conn_new(epp);
     78        rc = tcp_conn_add(nconn);
     79        if (rc != EOK) {
     80                tcp_conn_delete(nconn);
     81                return TCP_EEXISTS;
     82        }
     83
    7884        tcp_conn_lock(nconn);
    7985
     
    188194        /* Wait for data to become available */
    189195        while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin && !conn->reset) {
     196                tcp_conn_unlock(conn);
     197                return TCP_EAGAIN;
    190198                log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_receive() - wait for data");
    191199                fibril_condvar_wait(&conn->rcv_buf_cv, &conn->lock);
     
    250258                log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_close - listen/syn_sent");
    251259                tcp_conn_reset(conn);
    252                 tcp_conn_remove(conn);
    253260                tcp_conn_unlock(conn);
    254261                return TCP_EOK;
     
    294301}
    295302
    296 void tcp_uc_set_cstate_cb(tcp_conn_t *conn, tcp_cstate_cb_t cb, void *arg)
    297 {
    298         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_set_ctate_cb(%p, %p, %p)",
     303void tcp_uc_set_cb(tcp_conn_t *conn, tcp_cb_t *cb, void *arg)
     304{
     305        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_set_cb(%p, %p, %p)",
    299306            conn, cb, arg);
    300307
    301         conn->cstate_cb = cb;
    302         conn->cstate_cb_arg = arg;
     308        conn->cb = cb;
     309        conn->cb_arg = arg;
     310}
     311
     312void *tcp_uc_get_userptr(tcp_conn_t *conn)
     313{
     314        return conn->cb_arg;
    303315}
    304316
     
    308320
    309321/** Segment arrived */
    310 void tcp_as_segment_arrived(tcp_sockpair_t *sp, tcp_segment_t *seg)
     322void tcp_as_segment_arrived(inet_ep2_t *epp, tcp_segment_t *seg)
    311323{
    312324        tcp_conn_t *conn;
     
    314326        log_msg(LOG_DEFAULT, LVL_DEBUG,
    315327            "tcp_as_segment_arrived(f:(%u), l:(%u))",
    316             sp->foreign.port, sp->local.port);
    317 
    318         conn = tcp_conn_find_ref(sp);
     328            epp->remote.port, epp->local.port);
     329
     330        conn = tcp_conn_find_ref(epp);
    319331        if (conn == NULL) {
    320332                log_msg(LOG_DEFAULT, LVL_WARN, "No connection found.");
    321                 tcp_unexpected_segment(sp, seg);
     333                tcp_unexpected_segment(epp, seg);
    322334                return;
    323335        }
    324336
    325         tcp_conn_lock(conn);
    326 
    327         if (conn->cstate == st_closed) {
    328                 log_msg(LOG_DEFAULT, LVL_WARN, "Connection is closed.");
    329                 tcp_unexpected_segment(sp, seg);
    330                 tcp_conn_unlock(conn);
    331                 tcp_conn_delref(conn);
    332                 return;
    333         }
    334 
    335         if (inet_addr_is_any(&conn->ident.foreign.addr))
    336                 conn->ident.foreign.addr = sp->foreign.addr;
    337        
    338         if (conn->ident.foreign.port == TCP_PORT_ANY)
    339                 conn->ident.foreign.port = sp->foreign.port;
    340        
    341         if (inet_addr_is_any(&conn->ident.local.addr))
    342                 conn->ident.local.addr = sp->local.addr;
    343 
    344         tcp_conn_segment_arrived(conn, seg);
    345 
    346         tcp_conn_unlock(conn);
     337        tcp_conn_segment_arrived(conn, epp, seg);
    347338        tcp_conn_delref(conn);
    348339}
  • uspace/srv/net/tcp/ucall.h

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636#define UCALL_H
    3737
     38#include <inet/endpoint.h>
    3839#include <sys/types.h>
    3940#include "tcp_type.h"
     
    4243 * User calls
    4344 */
    44 extern tcp_error_t tcp_uc_open(tcp_sock_t *, tcp_sock_t *, acpass_t,
     45extern tcp_error_t tcp_uc_open(inet_ep2_t *, acpass_t,
    4546    tcp_open_flags_t, tcp_conn_t **);
    4647extern tcp_error_t tcp_uc_send(tcp_conn_t *, void *, size_t, xflags_t);
     
    5051extern void tcp_uc_status(tcp_conn_t *, tcp_conn_status_t *);
    5152extern void tcp_uc_delete(tcp_conn_t *);
    52 extern void tcp_uc_set_cstate_cb(tcp_conn_t *, tcp_cstate_cb_t, void *);
     53extern void tcp_uc_set_cb(tcp_conn_t *, tcp_cb_t *, void *);
     54extern void *tcp_uc_get_userptr(tcp_conn_t *);
    5355
    5456/*
    5557 * Arriving segments
    5658 */
    57 extern void tcp_as_segment_arrived(tcp_sockpair_t *, tcp_segment_t *);
     59extern void tcp_as_segment_arrived(inet_ep2_t *, tcp_segment_t *);
    5860
    5961/*
  • uspace/srv/net/udp/Makefile

    r0453261 ree1c2d9  
    2828
    2929USPACE_PREFIX = ../../..
    30 LIBS = $(LIBNET_PREFIX)/libnet.a
    31 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
     30
     31LIBS = \
     32        $(LIBNETTL_PREFIX)/libnettl.a
     33
     34EXTRA_CFLAGS += \
     35        -I$(LIBNETTL_PREFIX)/include
     36
    3237BINARY = udp
    3338
     
    3540        assoc.c \
    3641        msg.c \
    37         sock.c \
    3842        pdu.c \
    39         ucall.c \
     43        service.c \
    4044        udp.c \
    4145        udp_inet.c
  • uspace/srv/net/udp/assoc.c

    r0453261 ree1c2d9  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2015 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636
    3737#include <adt/list.h>
     38#include <errno.h>
    3839#include <stdbool.h>
    3940#include <fibril_synch.h>
     41#include <inet/endpoint.h>
    4042#include <io/log.h>
     43#include <nettl/amap.h>
    4144#include <stdlib.h>
    4245
     
    4447#include "msg.h"
    4548#include "pdu.h"
    46 #include "ucall.h"
    4749#include "udp_inet.h"
    4850#include "udp_type.h"
    4951
    50 LIST_INITIALIZE(assoc_list);
    51 FIBRIL_MUTEX_INITIALIZE(assoc_list_lock);
    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 *);
     52static LIST_INITIALIZE(assoc_list);
     53static FIBRIL_MUTEX_INITIALIZE(assoc_list_lock);
     54static amap_t *amap;
     55
     56static udp_assoc_t *udp_assoc_find_ref(inet_ep2_t *);
     57static int udp_assoc_queue_msg(udp_assoc_t *, inet_ep2_t *, udp_msg_t *);
     58
     59/** Initialize associations. */
     60int udp_assocs_init(void)
     61{
     62        int rc;
     63
     64        rc = amap_create(&amap);
     65        if (rc != EOK) {
     66                assert(rc == ENOMEM);
     67                return ENOMEM;
     68        }
     69
     70        return EOK;
     71}
    5772
    5873/** Create new association structure.
    5974 *
    60  * @param lsock         Local socket (will be deeply copied)
    61  * @param fsock         Foreign socket (will be deeply copied)
     75 * @param epp           Endpoint pair (will be copied)
     76 * @param cb            Callbacks
     77 * @param cb_arg        Callback argument
    6278 * @return              New association or NULL
    6379 */
    64 udp_assoc_t *udp_assoc_new(udp_sock_t *lsock, udp_sock_t *fsock)
     80udp_assoc_t *udp_assoc_new(inet_ep2_t *epp, udp_assoc_cb_t *cb, void *cb_arg)
    6581{
    6682        udp_assoc_t *assoc = NULL;
     
    8096        fibril_condvar_initialize(&assoc->rcv_queue_cv);
    8197
    82         if (lsock != NULL)
    83                 assoc->ident.local = *lsock;
    84        
    85         if (fsock != NULL)
    86                 assoc->ident.foreign = *fsock;
    87 
     98        if (epp != NULL)
     99                assoc->ident = *epp;
     100
     101        assoc->cb = cb;
     102        assoc->cb_arg = cb_arg;
    88103        return assoc;
    89104error:
     
    166181 * Add association to the association map.
    167182 */
    168 void udp_assoc_add(udp_assoc_t *assoc)
    169 {
     183int udp_assoc_add(udp_assoc_t *assoc)
     184{
     185        inet_ep2_t aepp;
     186        int rc;
     187
    170188        udp_assoc_addref(assoc);
    171189        fibril_mutex_lock(&assoc_list_lock);
     190
     191        rc = amap_insert(amap, &assoc->ident, assoc, af_allow_system, &aepp);
     192        if (rc != EOK) {
     193                udp_assoc_delref(assoc);
     194                fibril_mutex_unlock(&assoc_list_lock);
     195                return rc;
     196        }
     197
     198        assoc->ident = aepp;
    172199        list_append(&assoc->link, &assoc_list);
    173200        fibril_mutex_unlock(&assoc_list_lock);
     201
     202        return EOK;
    174203}
    175204
     
    181210{
    182211        fibril_mutex_lock(&assoc_list_lock);
     212        amap_remove(amap, &assoc->ident);
    183213        list_remove(&assoc->link);
    184214        fibril_mutex_unlock(&assoc_list_lock);
     
    196226            assoc, iplink);
    197227        fibril_mutex_lock(&assoc->lock);
    198         assoc->ident.iplink = iplink;
     228        assoc->ident.local_link = iplink;
    199229        fibril_mutex_unlock(&assoc->lock);
    200230}
    201231
    202 /** Set foreign socket in association.
    203  *
    204  * @param assoc         Association
    205  * @param fsock         Foreign socket (deeply copied)
    206  */
    207 void udp_assoc_set_foreign(udp_assoc_t *assoc, udp_sock_t *fsock)
    208 {
    209         log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_set_foreign(%p, %p)", assoc, fsock);
    210         fibril_mutex_lock(&assoc->lock);
    211         assoc->ident.foreign = *fsock;
    212         fibril_mutex_unlock(&assoc->lock);
    213 }
    214 
    215 /** Set local socket in association.
    216  *
    217  * @param assoc Association
    218  * @param lsock Local socket (deeply copied)
    219  *
    220  */
    221 void udp_assoc_set_local(udp_assoc_t *assoc, udp_sock_t *lsock)
    222 {
    223         log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_set_local(%p, %p)", assoc, lsock);
    224         fibril_mutex_lock(&assoc->lock);
    225         assoc->ident.local = *lsock;
    226         fibril_mutex_unlock(&assoc->lock);
    227 }
    228 
    229 /** Set local port in association.
    230  *
    231  * @param assoc Association
    232  * @param lport Local port
    233  *
    234  */
    235 void udp_assoc_set_local_port(udp_assoc_t *assoc, uint16_t lport)
    236 {
    237         log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_set_local(%p, %" PRIu16 ")", assoc, lport);
    238         fibril_mutex_lock(&assoc->lock);
    239         assoc->ident.local.port = lport;
    240         fibril_mutex_unlock(&assoc->lock);
    241 }
    242 
    243232/** Send message to association.
    244233 *
    245234 * @param assoc         Association
    246  * @param fsock         Foreign socket or NULL not to override @a assoc
     235 * @param remote        Remote endpoint or NULL not to override @a assoc
    247236 * @param msg           Message
    248237 *
    249238 * @return              EOK on success
    250  *                      EINVAL if foreign socket is not set
     239 *                      EINVAL if remote endpoint is not set
    251240 *                      ENOMEM if out of resources
    252241 *                      EIO if no route to destination exists
    253242 */
    254 int udp_assoc_send(udp_assoc_t *assoc, udp_sock_t *fsock, udp_msg_t *msg)
     243int udp_assoc_send(udp_assoc_t *assoc, inet_ep_t *remote, udp_msg_t *msg)
    255244{
    256245        udp_pdu_t *pdu;
    257         udp_sockpair_t sp;
     246        inet_ep2_t epp;
    258247        int rc;
    259248
    260249        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send(%p, %p, %p)",
    261             assoc, fsock, msg);
    262 
    263         /* @a fsock can be used to override the foreign socket */
    264         sp = assoc->ident;
    265         if (fsock != NULL)
    266                 sp.foreign = *fsock;
    267 
    268         if ((inet_addr_is_any(&sp.foreign.addr)) ||
    269             (sp.foreign.port == UDP_PORT_ANY))
     250            assoc, remote, msg);
     251
     252        /* @a remote can be used to override the remote endpoint */
     253        epp = assoc->ident;
     254        if (remote != NULL)
     255                epp.remote = *remote;
     256
     257        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send - check addr any");
     258
     259        if ((inet_addr_is_any(&epp.remote.addr)) ||
     260            (epp.remote.port == inet_port_any))
    270261                return EINVAL;
    271262
    272         rc = udp_pdu_encode(&sp, msg, &pdu);
     263        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send - check version");
     264
     265        if (epp.remote.addr.version != epp.local.addr.version)
     266                return EINVAL;
     267
     268        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send - encode pdu");
     269
     270        rc = udp_pdu_encode(&epp, msg, &pdu);
    273271        if (rc != EOK)
    274272                return ENOMEM;
    275273
     274        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send - transmit");
     275
    276276        rc = udp_transmit_pdu(pdu);
    277277        udp_pdu_delete(pdu);
     
    280280                return EIO;
    281281
     282        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send - success");
    282283        return EOK;
    283284}
     
    287288 * Pull one message from the association's receive queue.
    288289 */
    289 int udp_assoc_recv(udp_assoc_t *assoc, udp_msg_t **msg, udp_sock_t *fsock)
     290int udp_assoc_recv(udp_assoc_t *assoc, udp_msg_t **msg, inet_ep_t *remote)
    290291{
    291292        link_t *link;
     
    303304                log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_recv() - association was reset");
    304305                fibril_mutex_unlock(&assoc->lock);
    305                 return ECONNABORTED;
     306                return ENXIO;
    306307        }
    307308
     
    313314
    314315        *msg = rqe->msg;
    315         *fsock = rqe->sp.foreign;
     316        *remote = rqe->epp.remote;
    316317        free(rqe);
    317318
     
    323324 * Find the association to which the message belongs and queue it.
    324325 */
    325 void udp_assoc_received(udp_sockpair_t *rsp, udp_msg_t *msg)
     326void udp_assoc_received(inet_ep2_t *repp, udp_msg_t *msg)
    326327{
    327328        udp_assoc_t *assoc;
    328329        int rc;
    329330
    330         log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_received(%p, %p)", rsp, msg);
    331 
    332         assoc = udp_assoc_find_ref(rsp);
     331        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_received(%p, %p)", repp, msg);
     332
     333        assoc = udp_assoc_find_ref(repp);
    333334        if (assoc == NULL) {
    334335                log_msg(LOG_DEFAULT, LVL_DEBUG, "No association found. Message dropped.");
     
    339340        }
    340341
    341         rc = udp_assoc_queue_msg(assoc, rsp, msg);
    342         if (rc != EOK) {
    343                 log_msg(LOG_DEFAULT, LVL_DEBUG, "Out of memory. Message dropped.");
     342        if (0) {
     343                rc = udp_assoc_queue_msg(assoc, repp, msg);
     344                if (rc != EOK) {
     345                        log_msg(LOG_DEFAULT, LVL_DEBUG, "Out of memory. Message dropped.");
    344346                /* XXX Generate ICMP error? */
    345         }
     347                }
     348        }
     349
     350        log_msg(LOG_DEFAULT, LVL_DEBUG, "call assoc->cb->recv_msg");
     351        assoc->cb->recv_msg(assoc->cb_arg, repp, msg);
     352        udp_assoc_delref(assoc);
    346353}
    347354
     
    359366}
    360367
    361 static int udp_assoc_queue_msg(udp_assoc_t *assoc, udp_sockpair_