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

Changeset 0ac2158 in mainline


Ignore:
Timestamp:
2011-12-08T23:29:06Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
d9e14fa4
Parents:
5f9ecd3
Message:

Determine local IP address, fill it in pseudo header.

Location:
uspace/srv/net/tl/tcp
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/tcp/pdu.c

    r5f9ecd3 r0ac2158  
    4848#define TCP_CHECKSUM_INIT 0xffff
    4949
     50/** One's complement addition.
     51 *
     52 * Result is a + b + carry.
     53 */
     54static uint16_t tcp_ocadd16(uint16_t a, uint16_t b)
     55{
     56        uint32_t s;
     57
     58        s = (uint32_t)a + (uint32_t)b;
     59        return (s & 0xffff) + (s >> 16);
     60}
     61
    5062static uint16_t tcp_checksum_calc(uint16_t ivalue, void *data, size_t size)
    5163{
    5264        uint16_t sum;
     65        uint16_t w;
    5366        size_t words, i;
    5467        uint8_t *bdata;
     
    5972
    6073        for (i = 0; i < words; i++) {
    61                 sum += ~(((uint16_t)bdata[2*i] << 8) + bdata[2*i + 1]);
     74                w = ((uint16_t)bdata[2*i] << 8) | bdata[2*i + 1];
     75                sum = tcp_ocadd16(sum, w);
    6276        }
    6377
    6478        if (size % 2 != 0) {
    65                 sum += ~((uint16_t)bdata[2*words] << 8);
     79                w = ((uint16_t)bdata[2*words] << 8);
     80                sum = tcp_ocadd16(sum, w);
    6681        }
    6782
     
    237252
    238253        hdr = (tcp_header_t *)pdu->header;
    239         hdr->checksum = host2uint16_t_le(checksum);
     254        hdr->checksum = host2uint16_t_be(checksum);
    240255}
    241256
  • uspace/srv/net/tl/tcp/sock.c

    r5f9ecd3 r0ac2158  
    3939#include <errno.h>
    4040#include <io/log.h>
     41#include <ip_client.h>
    4142#include <ipc/socket.h>
    4243#include <net/modules.h>
     
    106107
    107108        sock->client = client;
     109        sock->laddr.ipv4 = TCP_IPV4_ANY;
    108110
    109111        sock_id = SOCKET_GET_SOCKET_ID(call);
     
    211213        tcp_sockdata_t *socket;
    212214        tcp_error_t trc;
     215        tcp_sock_t lsocket;
    213216        tcp_sock_t fsocket;
    214         uint16_t lport;
     217        device_id_t dev_id;
     218        tcp_phdr_t *phdr;
     219        size_t phdr_len;
    215220
    216221        log_msg(LVL_DEBUG, "tcp_sock_connect()");
     
    243248        }
    244249
    245         lport = sock_core->port;
     250        if (socket->laddr.ipv4 == TCP_IPV4_ANY) {
     251                /* Find route to determine local IP address. */
     252                rc = ip_get_route_req(ip_sess, IPPROTO_TCP,
     253                    (struct sockaddr *)addr, sizeof(*addr), &dev_id,
     254                    (void **)&phdr, &phdr_len);
     255                if (rc != EOK) {
     256                        async_answer_0(callid, rc);
     257                        log_msg(LVL_DEBUG, "tcp_transmit_connect: Failed to find route.");
     258                        return;
     259                }
     260
     261                socket->laddr.ipv4 = uint32_t_be2host(phdr->src_addr);
     262                log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4);
     263                free(phdr);
     264        }
     265
     266        lsocket.addr.ipv4 = socket->laddr.ipv4;
     267        lsocket.port = sock_core->port;
    246268        fsocket.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    247269        fsocket.port = uint16_t_be2host(addr->sin_port);
    248270
    249         trc = tcp_uc_open(lport, &fsocket, ap_active, &socket->conn);
     271        trc = tcp_uc_open(&lsocket, &fsocket, ap_active, &socket->conn);
    250272
    251273        if (socket->conn != NULL)
     
    280302        tcp_sockdata_t *asocket;
    281303        tcp_error_t trc;
     304        tcp_sock_t lsocket;
    282305        tcp_sock_t fsocket;
    283306        tcp_conn_t *conn;
     
    305328        log_msg(LVL_DEBUG, " - open connection");
    306329
     330        lsocket.addr.ipv4 = TCP_IPV4_ANY;
     331        lsocket.port = sock_core->port;
    307332        fsocket.addr.ipv4 = TCP_IPV4_ANY;
    308333        fsocket.port = TCP_PORT_ANY;
    309334
    310         trc = tcp_uc_open(sock_core->port, &fsocket, ap_passive, &conn);
     335        trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, &conn);
    311336        if (conn != NULL)
    312337                conn->name = (char *)"S";
  • uspace/srv/net/tl/tcp/tcp.c

    r5f9ecd3 r0ac2158  
    6464async_sess_t *net_sess;
    6565static async_sess_t *icmp_sess;
    66 static async_sess_t *ip_sess;
     66async_sess_t *ip_sess;
    6767packet_dimensions_t pkt_dims;
    6868
  • uspace/srv/net/tl/tcp/tcp.h

    r5f9ecd3 r0ac2158  
    4141
    4242extern async_sess_t *net_sess;
     43extern async_sess_t *ip_sess;
    4344extern void tcp_transmit_pdu(tcp_pdu_t *);
    4445
  • uspace/srv/net/tl/tcp/tcp_type.h

    r5f9ecd3 r0ac2158  
    304304
    305305typedef struct {
     306        /** Client */
    306307        tcp_client_t *client;
     308        /** Connection */
    307309        tcp_conn_t *conn;
     310        /** Local address */
     311        netaddr_t laddr;
    308312} tcp_sockdata_t;
    309313
  • uspace/srv/net/tl/tcp/test.c

    r5f9ecd3 r0ac2158  
    5050{
    5151        tcp_conn_t *conn;
    52         tcp_sock_t sock;
     52        tcp_sock_t lsock;
     53        tcp_sock_t fsock;
    5354        char rcv_buf[RCV_BUF_SIZE + 1];
    5455        size_t rcvd;
     
    5657
    5758        printf("test_srv()\n");
    58         sock.port = 1024;
    59         sock.addr.ipv4 = 0x7f000001;
     59        lsock.port = 80;
     60        lsock.addr.ipv4 = 0x7f000001;
     61        fsock.port = 1024;
     62        fsock.addr.ipv4 = 0x7f000001;
    6063        printf("S: User open...\n");
    61         tcp_uc_open(80, &sock, ap_passive, &conn);
     64        tcp_uc_open(&lsock, &fsock, ap_passive, &conn);
    6265        conn->name = (char *) "S";
    6366
     
    8689{
    8790        tcp_conn_t *conn;
    88         tcp_sock_t sock;
     91        tcp_sock_t lsock;
     92        tcp_sock_t fsock;
    8993        const char *msg = "Hello World!";
    9094
    9195        printf("test_cli()\n");
    9296
    93         sock.port = 80;
    94         sock.addr.ipv4 = 0x7f000001;
     97        lsock.port = 1024;
     98        lsock.addr.ipv4 = 0x7f000001;
     99        fsock.port = 80;
     100        fsock.addr.ipv4 = 0x7f000001;
    95101
    96102        async_usleep(1000*1000*3);
    97103        printf("C: User open...\n");
    98         tcp_uc_open(1024, &sock, ap_active, &conn);
     104        tcp_uc_open(&lsock, &fsock, ap_active, &conn);
    99105        conn->name = (char *) "C";
    100106
  • uspace/srv/net/tl/tcp/ucall.c

    r5f9ecd3 r0ac2158  
    5050/** OPEN user call
    5151 *
    52  * @param lport         Local port
     52 * @param lsock         Local socket
    5353 * @param fsock         Foreign socket
    5454 * @param acpass        Active/passive
    5555 * @param conn          Connection
     56 *
     57 * Unlike in the spec we allow specifying the local address. This means
     58 * the implementation does not need to magically guess it, especially
     59 * considering there can be more than one local address.
    5660 *
    5761 * XXX We should be able to call active open on an existing listening
     
    6064 * establishment.
    6165 */
    62 tcp_error_t tcp_uc_open(uint16_t lport, tcp_sock_t *fsock, acpass_t acpass,
     66tcp_error_t tcp_uc_open(tcp_sock_t *lsock, tcp_sock_t *fsock, acpass_t acpass,
    6367    tcp_conn_t **conn)
    6468{
    6569        tcp_conn_t *nconn;
    66         tcp_sock_t lsock;
    67 
    68         log_msg(LVL_DEBUG, "tcp_uc_open(%" PRIu16 ", %p, %s, %p)",
    69             lport, fsock, acpass == ap_active ? "active" : "passive",
     70
     71        log_msg(LVL_DEBUG, "tcp_uc_open(%p, %p, %s, %p)",
     72            lsock, fsock, acpass == ap_active ? "active" : "passive",
    7073            conn);
    7174
    72         lsock.port = lport;
    73         lsock.addr.ipv4 = TCP_IPV4_ANY;
    74 
    75         nconn = tcp_conn_new(&lsock, fsock);
     75        nconn = tcp_conn_new(lsock, fsock);
    7676        tcp_conn_add(nconn);
    7777
     
    246246                if (conn->ident.foreign.port == TCP_PORT_ANY)
    247247                        conn->ident.foreign.port = sp->foreign.port;
     248                if (conn->ident.local.addr.ipv4 == TCP_IPV4_ANY)
     249                        conn->ident.local.addr.ipv4 = sp->local.addr.ipv4;
    248250
    249251                tcp_conn_segment_arrived(conn, seg);
  • uspace/srv/net/tl/tcp/ucall.h

    r5f9ecd3 r0ac2158  
    4242 * User calls
    4343 */
    44 extern tcp_error_t tcp_uc_open(uint16_t, tcp_sock_t *, acpass_t, tcp_conn_t **);
     44extern tcp_error_t tcp_uc_open(tcp_sock_t *, tcp_sock_t *, acpass_t, tcp_conn_t **);
    4545extern tcp_error_t tcp_uc_send(tcp_conn_t *, void *, size_t, xflags_t);
    4646extern tcp_error_t tcp_uc_receive(tcp_conn_t *, void *, size_t, size_t *, xflags_t *);
Note: See TracChangeset for help on using the changeset viewer.