~as-s/helenos/ipv6

« back to all changes in this revision

Viewing changes to uspace/srv/net/tcp/sock.c

  • Committer: Anthony Steinhauser
  • Date: 2013-07-08 01:07:36 UTC
  • Revision ID: as@strmilov.cz-20130708010736-pbvrszhamp0v64ez
HelenOS networking stack supports IPv6

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (c) 2008 Lukas Mejdrech
3
3
 * Copyright (c) 2011 Jiri Svoboda
 
4
 * Copyright (c) 2013 Antonin Steinhauser
4
5
 * All rights reserved.
5
6
 *
6
7
 * Redistribution and use in source and binary forms, with or without
178
179
                return;
179
180
        }
180
181
 
181
 
        sock->laddr.s_addr = INADDR_ANY;
 
182
        sock->laddr = in6addr_any;
182
183
        sock->lconn = NULL;
183
184
        sock->backlog = 0;
184
185
 
202
203
static void tcp_sock_bind(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
203
204
{
204
205
        int rc;
205
 
        struct sockaddr_in *addr;
 
206
        struct sockaddr_in6 *addr;
206
207
        size_t addr_size;
207
208
        socket_core_t *sock_core;
208
209
        tcp_sockdata_t *socket;
218
219
                goto out;
219
220
        }
220
221
        
221
 
        if (addr_size != sizeof(struct sockaddr_in)) {
 
222
        if (addr_size != sizeof(struct sockaddr_in6)) {
222
223
                async_answer_0(callid, EINVAL);
223
224
                goto out;
224
225
        }
313
314
        
314
315
        log_msg(LOG_DEFAULT, LVL_DEBUG, " - open connections");
315
316
        
316
 
        lsocket.addr.s_addr = INADDR_ANY;
 
317
        lsocket.addr = in6addr_any;
317
318
        lsocket.port = sock_core->port;
318
 
        fsocket.addr.s_addr = INADDR_ANY;
 
319
        fsocket.addr = in6addr_any;
319
320
        fsocket.port = TCP_PORT_ANY;
320
321
        
321
322
        for (i = 0; i < backlog; i++) {
355
356
static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
356
357
{
357
358
        int rc;
358
 
        struct sockaddr_in *addr;
 
359
        struct sockaddr_in6 *addr;
359
360
        int socket_id;
360
361
        size_t addr_len;
361
362
        socket_core_t *sock_core;
367
368
        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect()");
368
369
 
369
370
        rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len);
370
 
        if (rc != EOK || addr_len != sizeof(struct sockaddr_in)) {
 
371
        if (rc != EOK || addr_len != sizeof(struct sockaddr_in6)) {
371
372
                async_answer_0(callid, rc);
372
373
                return;
373
374
        }
395
396
 
396
397
        fibril_mutex_lock(&socket->lock);
397
398
 
398
 
        if (socket->laddr.s_addr == INADDR_ANY) {
 
399
        if (in6addr_equal(&socket->laddr, &in6addr_any)) {
399
400
                /* Determine local IP address */
400
 
                in_addr_t loc_addr, rem_addr;
 
401
                in6_addr_t loc_addr, rem_addr;
401
402
 
402
 
                rem_addr.s_addr = addr->sin_addr.s_addr;
 
403
                rem_addr = addr->sin6_addr;
403
404
                rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
404
405
                if (rc != EOK) {
405
406
                        fibril_mutex_unlock(&socket->lock);
409
410
                        return;
410
411
                }
411
412
 
412
 
                socket->laddr.s_addr = loc_addr.s_addr;
413
 
                log_msg(LOG_DEFAULT, LVL_DEBUG, "Local IP address is %x", socket->laddr.s_addr);
 
413
                socket->laddr = loc_addr;
414
414
        }
415
415
 
416
 
        lsocket.addr.s_addr = socket->laddr.s_addr;
 
416
        lsocket.addr = socket->laddr;
417
417
        lsocket.port = sock_core->port;
418
 
        fsocket.addr.s_addr = addr->sin_addr.s_addr;
419
 
        fsocket.port = uint16_t_be2host(addr->sin_port);
 
418
        fsocket.addr = addr->sin6_addr;
 
419
        fsocket.port = uint16_t_be2host(addr->sin6_port);
420
420
 
421
421
        trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn);
422
422
 
506
506
 
507
507
        /* Replenish listening connection */
508
508
 
509
 
        lsocket.addr.s_addr = INADDR_ANY;
 
509
        lsocket.addr = in6addr_any;
510
510
        lsocket.port = sock_core->port;
511
 
        fsocket.addr.s_addr = INADDR_ANY;
 
511
        fsocket.addr = in6addr_any;
512
512
        fsocket.port = TCP_PORT_ANY;
513
513
 
514
514
        trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, tcp_open_nonblock,
553
553
 
554
554
        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
555
555
        SOCKET_SET_SOCKET_ID(answer, asock_id);
556
 
        SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in));
 
556
        SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in6));
 
557
 
 
558
        struct sockaddr_in6 sa;
 
559
        memset(&sa, 0, sizeof(struct sockaddr_in6));
 
560
        sa.sin6_family = AF_INET6;
 
561
        sa.sin6_addr = asocket->conn->ident.foreign.addr;
 
562
        sa.sin6_port = asocket->conn->ident.foreign.port;
 
563
 
 
564
        ipc_callid_t rcallid;
 
565
        size_t sockl;
 
566
 
 
567
        if (!async_data_read_receive(&rcallid, &sockl))
 
568
        {
 
569
                /* XXX Clean up */
 
570
                fibril_mutex_unlock(&socket->lock);
 
571
                async_answer_0(callid, ENOMEM);
 
572
                return;
 
573
        }
 
574
 
 
575
        async_data_read_finalize(rcallid, &sa, sizeof(struct sockaddr_in6));
557
576
        
558
577
        async_answer_3(callid, asocket->sock_core->socket_id,
559
578
            IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
574
593
        ipc_call_t answer;
575
594
        ipc_callid_t wcallid;
576
595
        size_t length;
577
 
        uint8_t buffer[TCP_SOCK_FRAGMENT_SIZE];
 
596
        uint8_t * buffer = NULL;
578
597
        tcp_error_t trc;
579
598
        int rc;
580
599
 
598
617
                return;
599
618
        }
600
619
 
 
620
        buffer = calloc(TCP_SOCK_FRAGMENT_SIZE, 1);
 
621
 
601
622
        for (index = 0; index < fragments; index++) {
602
623
                if (!async_data_write_receive(&wcallid, &length)) {
603
624
                        fibril_mutex_unlock(&socket->lock);
604
625
                        async_answer_0(callid, EINVAL);
 
626
                        free(buffer);
605
627
                        return;
606
628
                }
607
629
 
612
634
                if (rc != EOK) {
613
635
                        fibril_mutex_unlock(&socket->lock);
614
636
                        async_answer_0(callid, rc);
 
637
                        free(buffer);
615
638
                        return;
616
639
                }
617
640
 
637
660
                if (rc != EOK) {
638
661
                        fibril_mutex_unlock(&socket->lock);
639
662
                        async_answer_0(callid, rc);
 
663
                        free(buffer);
640
664
                        return;
641
665
                }
642
666
        }
643
667
 
 
668
        free(buffer);
 
669
 
644
670
        IPC_SET_ARG1(answer, 0);
645
671
        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
646
672
        async_answer_2(callid, EOK, IPC_GET_ARG1(answer),
664
690
        ipc_call_t answer;
665
691
        ipc_callid_t rcallid;
666
692
        size_t data_len;
667
 
        struct sockaddr_in addr;
 
693
        struct sockaddr_in6 addr;
668
694
        tcp_sock_t *rsock;
669
695
        int rc;
670
696
 
729
755
        if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
730
756
                /* Fill addr */
731
757
                rsock = &socket->conn->ident.foreign;
732
 
                addr.sin_family = AF_INET;
733
 
                addr.sin_addr.s_addr = rsock->addr.s_addr;
734
 
                addr.sin_port = host2uint16_t_be(rsock->port);
 
758
                addr.sin6_family = AF_INET6;
 
759
                addr.sin6_addr = rsock->addr;
 
760
                addr.sin6_port = host2uint16_t_be(rsock->port);
735
761
 
736
762
                log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
737
763
                if (!async_data_read_receive(&rcallid, &addr_length)) {