Subversion Repositories HelenOS

Rev

Rev 4713 | Rev 4722 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4713 Rev 4720
Line 48... Line 48...
48
 
48
 
49
#include "../../structures/dynamic_fifo.h"
49
#include "../../structures/dynamic_fifo.h"
50
#include "../../structures/packet/packet_client.h"
50
#include "../../structures/packet/packet_client.h"
51
 
51
 
52
#include "../../include/in.h"
52
#include "../../include/in.h"
-
 
53
#include "../../include/in6.h"
53
#include "../../include/inet.h"
54
#include "../../include/inet.h"
54
#include "../../include/ip_client.h"
55
#include "../../include/ip_client.h"
55
#include "../../include/ip_interface.h"
56
#include "../../include/ip_interface.h"
56
#include "../../include/ip_protocols.h"
57
#include "../../include/ip_protocols.h"
57
#include "../../include/icmp_client.h"
58
#include "../../include/icmp_client.h"
Line 128... Line 129...
128
int udp_process_client_messages( ipc_callid_t callid, ipc_call_t call );
129
int udp_process_client_messages( ipc_callid_t callid, ipc_call_t call );
129
 
130
 
130
/** Sends data from the socket to the remote address.
131
/** Sends data from the socket to the remote address.
131
 *  Binds the socket to a free port if not already connected/bound.
132
 *  Binds the socket to a free port if not already connected/bound.
132
 *  Handles the NET_SOCKET_SENDTO message.
133
 *  Handles the NET_SOCKET_SENDTO message.
-
 
134
 *  Supports AF_INET and AF_INET6 address families.
133
 *  @param local_sockets The application local sockets. Input/output parameter.
135
 *  @param local_sockets The application local sockets. Input/output parameter.
134
 *  @param socket_id Socket identifier. Input parameter.
136
 *  @param socket_id Socket identifier. Input parameter.
135
 *  @param addr The destination address. Input parameter.
137
 *  @param addr The destination address. Input parameter.
136
 *  @param addrlen The address length. Input parameter.
138
 *  @param addrlen The address length. Input parameter.
137
 *  @param fragments The number of data fragments. Input parameter.
139
 *  @param fragments The number of data fragments. Input parameter.
Line 144... Line 146...
144
 *  @returns ENOMEM if there is not enough memory left.
146
 *  @returns ENOMEM if there is not enough memory left.
145
 *  @returns Other error codes as defined for the socket_read_packet_data() function.
147
 *  @returns Other error codes as defined for the socket_read_packet_data() function.
146
 *  @returns Other error codes as defined for the ip_client_prepare_packet() function.
148
 *  @returns Other error codes as defined for the ip_client_prepare_packet() function.
147
 *  @returns Other error codes as defined for the ip_send_msg() function.
149
 *  @returns Other error codes as defined for the ip_send_msg() function.
148
 */
150
 */
149
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, void * addr, size_t addrlen, int fragments, int flags );
151
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, int flags );
150
 
152
 
151
/** Receives data to the socket.
153
/** Receives data to the socket.
152
 *  Handles the NET_SOCKET_RECVFROM message.
154
 *  Handles the NET_SOCKET_RECVFROM message.
-
 
155
 *  Replies the source address as well.
153
 *  @param local_sockets The application local sockets. Input parameter.
156
 *  @param local_sockets The application local sockets. Input parameter.
154
 *  @param socket_id Socket identifier. Input parameter.
157
 *  @param socket_id Socket identifier. Input parameter.
155
 *  @param flags Various receive flags. Input parameter.
158
 *  @param flags Various receive flags. Input parameter.
-
 
159
 *  @param addrlen The source address length. Output parameter.
156
 *  @returns The number of bytes received.
160
 *  @returns The number of bytes received.
157
 *  @returns ENOTSOCK if the socket is not found.
161
 *  @returns ENOTSOCK if the socket is not found.
158
 *  @returns NO_DATA if there are no received packets or data.
162
 *  @returns NO_DATA if there are no received packets or data.
159
 *  @returns ENOMEM if there is not enough memory left.
163
 *  @returns ENOMEM if there is not enough memory left.
160
 *  @returns EINVAL if the received address is not an IP address.
164
 *  @returns EINVAL if the received address is not an IP address.
161
 *  @returns Other error codes as defined for the packet_translate() function.
165
 *  @returns Other error codes as defined for the packet_translate() function.
162
 *  @returns Other error codes as defined for the socket_write_data() function.
166
 *  @returns Other error codes as defined for the socket_write_data() function.
163
 */
167
 */
164
int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags );
168
int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen );
165
 
169
 
166
/*@}*/
170
/*@}*/
167
 
171
 
168
/** Receives data from the socket.
172
/** Receives data from the socket.
169
 *  The received data buffer is allocated and returned.
173
 *  The received data buffer is allocated and returned.
Line 178... Line 182...
178
int socket_read_data( void ** data, size_t * length );
182
int socket_read_data( void ** data, size_t * length );
179
 
183
 
180
/** Receives data from the socket into a packet.
184
/** Receives data from the socket into a packet.
181
 *  @param packet The new created packet. Output parameter.
185
 *  @param packet The new created packet. Output parameter.
182
 *  @param prefix Reserved packet data prefix length. Input parameter.
186
 *  @param prefix Reserved packet data prefix length. Input parameter.
183
 *  @param address_in The destination address to be set. Input parameter.
187
 *  @param addr The destination address. Input parameter.
-
 
188
 *  @param addrlen The address length. Input parameter.
184
 *  @returns Number of bytes received.
189
 *  @returns Number of bytes received.
185
 *  @returns EINVAL if the client does not send data.
190
 *  @returns EINVAL if the client does not send data.
186
 *  @returns ENOMEM if there is not enough memory left.
191
 *  @returns ENOMEM if there is not enough memory left.
187
 *  @returns Other error codes as defined for the ipc_data_read_finalize() function.
192
 *  @returns Other error codes as defined for the ipc_data_read_finalize() function.
188
 */
193
 */
189
int socket_read_packet_data( packet_ref packet, size_t prefix, struct sockaddr_in * address_in );
194
int socket_read_packet_data( packet_ref packet, size_t prefix, const struct sockaddr * addr, socklen_t addrlen );
190
 
195
 
191
/** Replies the data to the socket.
196
/** Replies the data to the socket.
192
 *  @param data The data buffer to be sent. Input parameter.
197
 *  @param data The data buffer to be sent. Input parameter.
193
 *  @param data_length The buffer length. Input parameter.
198
 *  @param data_length The buffer length. Input parameter.
194
 *  @returns EOK on success.
199
 *  @returns EOK on success.
195
 *  @returns EINVAL if the client does not expect all the data.
200
 *  @returns EINVAL if the client does not expect all the data.
196
 *  @returns Other error codes as defined for the ipc_data_read_finalize() function.
201
 *  @returns Other error codes as defined for the ipc_data_read_finalize() function.
197
 */
202
 */
198
int socket_write_data( void * data, size_t data_length );
203
int socket_write_data( void * data, size_t data_length );
199
 
204
 
-
 
205
/** Sets the address port.
-
 
206
 *  Supports AF_INET and AF_INET6 address families.
-
 
207
 *  @param addr The address to be updated. Input/output parameter.
-
 
208
 *  @param addrlen The address length. Input parameter.
-
 
209
 *  @param port The port to be set. Input parameter.
-
 
210
 *  @returns EOK on success.
-
 
211
 *  @returns EINVAL if the address length does not match the address family.
-
 
212
 *  @returns EAFNOSUPPORT if the address family is not supported.
-
 
213
 */
-
 
214
int udp_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port );
-
 
215
 
200
/** UDP global data.
216
/** UDP global data.
201
 */
217
 */
202
udp_globals_t   udp_globals;
218
udp_globals_t   udp_globals;
203
 
219
 
204
int udp_initialize( async_client_conn_t client_connection ){
220
int udp_initialize( async_client_conn_t client_connection ){
Line 350... Line 366...
350
int udp_process_client_messages( ipc_callid_t callid, ipc_call_t call ){
366
int udp_process_client_messages( ipc_callid_t callid, ipc_call_t call ){
351
    int                     res;
367
    int                     res;
352
    bool                    keep_on_going = true;
368
    bool                    keep_on_going = true;
353
    socket_cores_t          local_sockets;
369
    socket_cores_t          local_sockets;
354
    int                     app_phone = IPC_GET_PHONE( & call );
370
    int                     app_phone = IPC_GET_PHONE( & call );
355
    void *                  addr;
371
    struct sockaddr *       addr;
356
    size_t                  addrlen;
372
    size_t                  addrlen;
357
    fibril_rwlock_t         lock;
373
    fibril_rwlock_t         lock;
358
    ipc_call_t              answer;
374
    ipc_call_t              answer;
359
    int                     answer_count;
375
    int                     answer_count;
360
 
376
 
Line 386... Line 402...
386
                * SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t );
402
                * SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t );
387
                * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE;
403
                * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE;
388
                answer_count = 3;
404
                answer_count = 3;
389
                break;
405
                break;
390
            case NET_SOCKET_BIND:
406
            case NET_SOCKET_BIND:
391
                res = socket_read_data( & addr, & addrlen );
407
                res = socket_read_data(( void ** ) & addr, & addrlen );
392
                if( res == EOK ){
408
                if( res == EOK ){
393
                    fibril_rwlock_write_lock( & lock );
409
                    fibril_rwlock_write_lock( & lock );
394
                    fibril_rwlock_write_lock( & udp_globals.lock );
410
                    fibril_rwlock_write_lock( & udp_globals.lock );
395
                    res = socket_bind( & local_sockets, & udp_globals.sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port );
411
                    res = socket_bind( & local_sockets, & udp_globals.sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port );
396
                    fibril_rwlock_write_unlock( & udp_globals.lock );
412
                    fibril_rwlock_write_unlock( & udp_globals.lock );
397
                    fibril_rwlock_write_unlock( & lock );
413
                    fibril_rwlock_write_unlock( & lock );
398
                    free( addr );
414
                    free( addr );
399
                }
415
                }
400
                break;
416
                break;
401
            case NET_SOCKET_SENDTO:
417
            case NET_SOCKET_SENDTO:
402
                res = socket_read_data( & addr, & addrlen );
418
                res = socket_read_data(( void ** ) & addr, & addrlen );
403
                if( res == EOK ){
419
                if( res == EOK ){
404
                    fibril_rwlock_read_lock( & lock );
420
                    fibril_rwlock_read_lock( & lock );
405
                    fibril_rwlock_read_lock( & udp_globals.lock );
421
                    fibril_rwlock_read_lock( & udp_globals.lock );
406
                    res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_FLAGS( call ));
422
                    res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_FLAGS( call ));
407
                    fibril_rwlock_read_unlock( & udp_globals.lock );
423
                    fibril_rwlock_read_unlock( & udp_globals.lock );
Line 410... Line 426...
410
                }
426
                }
411
                break;
427
                break;
412
            case NET_SOCKET_RECVFROM:
428
            case NET_SOCKET_RECVFROM:
413
                fibril_rwlock_read_lock( & lock );
429
                fibril_rwlock_read_lock( & lock );
414
                fibril_rwlock_read_lock( & udp_globals.lock );
430
                fibril_rwlock_read_lock( & udp_globals.lock );
415
                res = udp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ));
431
                res = udp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ), & addrlen );
416
                fibril_rwlock_read_unlock( & udp_globals.lock );
432
                fibril_rwlock_read_unlock( & udp_globals.lock );
417
                fibril_rwlock_read_unlock( & lock );
433
                fibril_rwlock_read_unlock( & lock );
418
                if( res > 0 ){
434
                if( res > 0 ){
419
                    * SOCKET_SET_READ_DATA_LENGTH( answer ) = res;
435
                    * SOCKET_SET_READ_DATA_LENGTH( answer ) = res;
420
                    * SOCKET_SET_ADDRESS_LENGTH( answer ) = sizeof( struct sockaddr_in );
436
                    * SOCKET_SET_ADDRESS_LENGTH( answer ) = addrlen;
421
                    answer_count = 2;
437
                    answer_count = 2;
422
                    res = EOK;
438
                    res = EOK;
423
                }
439
                }
424
                break;
440
                break;
425
            case NET_SOCKET_CLOSE:
441
            case NET_SOCKET_CLOSE:
Line 444... Line 460...
444
    socket_cores_destroy( & local_sockets );
460
    socket_cores_destroy( & local_sockets );
445
 
461
 
446
    return EOK;
462
    return EOK;
447
}
463
}
448
 
464
 
449
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, void * addr, size_t addrlen, int fragments, int flags ){
465
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, int flags ){
450
    ERROR_DECLARE;
466
    ERROR_DECLARE;
451
 
467
 
452
    socket_core_ref         socket;
468
    socket_core_ref         socket;
453
    struct sockaddr *       address;
-
 
454
    struct sockaddr_in *    address_in;
469
    struct sockaddr_in *    address_in;
-
 
470
    struct sockaddr_in6 *   address_in6;
455
    packet_t                packet;
471
    packet_t                packet;
456
    packet_t                next_packet;
472
    packet_t                next_packet;
457
    udp_header_ref          header;
473
    udp_header_ref          header;
458
    int                     index;
474
    int                     index;
459
    size_t                  total_length;
475
    size_t                  total_length;
460
    int                     result;
476
    int                     result;
-
 
477
    uint16_t                dest_port;
461
 
478
 
462
    if( addrlen < sizeof( struct sockaddr )) return EINVAL;
479
    if( addrlen < sizeof( struct sockaddr )) return EINVAL;
463
    address = ( struct sockaddr * ) addr;
-
 
464
    switch( address->sa_family ){
480
    switch( addr->sa_family ){
465
        case AF_INET:
481
        case AF_INET:
466
            if( addrlen != sizeof( struct sockaddr_in )) return EINVAL;
482
            if( addrlen != sizeof( struct sockaddr_in )) return EINVAL;
467
            address_in = ( struct sockaddr_in * ) addr;
483
            address_in = ( struct sockaddr_in * ) addr;
-
 
484
            dest_port = address_in->sin_port;
-
 
485
            break;
-
 
486
        case AF_INET6:
468
            socket = socket_cores_find( local_sockets, socket_id );
487
            if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
-
 
488
            address_in6 = ( struct sockaddr_in6 * ) addr;
-
 
489
            dest_port = address_in6->sin6_port;
-
 
490
            break;
-
 
491
        default:
469
            if( ! socket ) return ENOTSOCK;
492
            return EAFNOSUPPORT;
-
 
493
    }
470
 
494
 
471
            // bind the socket to a random free port if not bound
-
 
472
            while( socket->port <= 0 ){
-
 
473
                // try to find a free port
-
 
474
                fibril_rwlock_read_unlock( & udp_globals.lock );
-
 
475
                fibril_rwlock_write_lock( & udp_globals.lock );
495
    socket = socket_cores_find( local_sockets, socket_id );
476
                if( socket->port <= 0 ){
496
    if( ! socket ) return ENOTSOCK;
477
                    ERROR_PROPAGATE( socket_bind_free_port( & udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port ));
-
 
478
                    // set the next port as the search starting port number
-
 
479
                    udp_globals.last_used_port = socket->port;
-
 
480
                }
-
 
481
                fibril_rwlock_write_unlock( & udp_globals.lock );
-
 
482
                fibril_rwlock_read_lock( & udp_globals.lock );
-
 
483
            }
-
 
484
            // TODO do not ask all the time
-
 
485
            ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix ));
-
 
486
 
497
 
487
            // read the first packet fragment
498
    // bind the socket to a random free port if not bound
488
            result = socket_read_packet_data( & packet, sizeof( udp_header_t ), address_in );
-
 
489
            if( result < 0 ) return result;
499
    while( socket->port <= 0 ){
490
            total_length = ( size_t ) result;
500
        // try to find a free port
491
            // prefix the udp header
501
        fibril_rwlock_read_unlock( & udp_globals.lock );
492
            header = PACKET_PREFIX( packet, udp_header_t );
502
        fibril_rwlock_write_lock( & udp_globals.lock );
493
            if( ! header ){
503
        if( socket->port <= 0 ){
494
                pq_release( udp_globals.net_phone, packet_get_id( packet ));
504
            ERROR_PROPAGATE( socket_bind_free_port( & udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port ));
495
                return ENOMEM;
-
 
496
            }
-
 
497
            // read the rest of the packet fragments
505
            // set the next port as the search starting port number
498
            for( index = 1; index < fragments; ++ index ){
-
 
499
                result = socket_read_packet_data( & next_packet, 0, address_in );
-
 
500
                if( result < 0 ){
-
 
501
                    return udp_release_and_return( packet, result );
506
            udp_globals.last_used_port = socket->port;
502
                }
507
        }
503
                packet = pq_add( packet, next_packet, index, 0 );
508
        fibril_rwlock_write_unlock( & udp_globals.lock );
504
                total_length += ( size_t ) result;
509
        fibril_rwlock_read_lock( & udp_globals.lock );
505
            }
510
    }
-
 
511
 
506
            // set the udp header
512
    // TODO do not ask all the time
507
            header->source = htons( socket->port );
513
    ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix ));
-
 
514
 
508
            header->dest = htons( address_in->sin_port );
515
    // read the first packet fragment
509
            header->len = htons( total_length + sizeof( udp_header_t ));
516
    result = socket_read_packet_data( & packet, sizeof( udp_header_t ), addr, addrlen );
510
            // TODO my ip address for the pseudo header checksum
517
    if( result < 0 ) return result;
511
            header->check = 0;
518
    total_length = ( size_t ) result;
512
            // prepare the first packet fragment
519
    // prefix the udp header
513
            if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_UDP, 0, 0, 0, 0 ))){
-
 
514
                pq_release( udp_globals.net_phone, packet_get_id( packet ));
520
    header = PACKET_PREFIX( packet, udp_header_t );
515
                return ERROR_CODE;
-
 
516
            }
-
 
517
            // send the packet
521
    if( ! header ){
518
            return ip_send_msg( udp_globals.ip_phone, socket->device_id, packet, SERVICE_UDP, 0 );
522
        pq_release( udp_globals.net_phone, packet_get_id( packet ));
519
        // TODO IPv6
523
        return ENOMEM;
520
    }
524
    }
-
 
525
    // read the rest of the packet fragments
-
 
526
    for( index = 1; index < fragments; ++ index ){
-
 
527
        result = socket_read_packet_data( & next_packet, 0, addr, addrlen );
-
 
528
        if( result < 0 ){
-
 
529
            return udp_release_and_return( packet, result );
-
 
530
        }
-
 
531
        packet = pq_add( packet, next_packet, index, 0 );
-
 
532
        total_length += ( size_t ) result;
-
 
533
    }
-
 
534
    // set the udp header
-
 
535
    header->source = htons( socket->port );
-
 
536
    header->dest = htons( dest_port );
-
 
537
    header->len = htons( total_length + sizeof( udp_header_t ));
-
 
538
    // TODO my ip address for the pseudo header checksum
-
 
539
    header->check = 0;
-
 
540
    // prepare the first packet fragment
-
 
541
    if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_UDP, 0, 0, 0, 0 ))){
-
 
542
        pq_release( udp_globals.net_phone, packet_get_id( packet ));
521
    return EAFNOSUPPORT;
543
        return ERROR_CODE;
-
 
544
    }
-
 
545
    // send the packet
-
 
546
    return ip_send_msg( udp_globals.ip_phone, socket->device_id, packet, SERVICE_UDP, 0 );
522
}
547
}
523
 
548
 
524
int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags ){
549
int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen ){
525
    ERROR_DECLARE;
550
    ERROR_DECLARE;
526
 
551
 
527
    socket_core_ref socket;
552
    socket_core_ref socket;
528
    int             packet_id;
553
    int             packet_id;
529
    packet_t        packet;
554
    packet_t        packet;
530
    udp_header_ref  header;
555
    udp_header_ref  header;
531
    struct sockaddr_in      address;
556
    struct sockaddr *   addr;
532
    size_t          length;
557
    size_t          length;
533
    packet_t        next_packet;
558
    packet_t        next_packet;
534
    uint8_t *       data;
559
    uint8_t *       data;
535
    size_t          fragments;
560
    size_t          fragments;
536
    size_t *        lengths;
561
    size_t *        lengths;
537
    int             result;
-
 
538
    size_t          index;
562
    size_t          index;
539
    uint8_t *       addr;
563
    int             result;
540
 
564
 
541
    // find the socket
565
    // find the socket
542
    socket = socket_cores_find( local_sockets, socket_id );
566
    socket = socket_cores_find( local_sockets, socket_id );
543
    if( ! socket ) return ENOTSOCK;
567
    if( ! socket ) return ENOTSOCK;
544
    // get the next received packet
568
    // get the next received packet
Line 550... Line 574...
550
    if( ! data ){
574
    if( ! data ){
551
        pq_release( udp_globals.net_phone, packet_id );
575
        pq_release( udp_globals.net_phone, packet_id );
552
        return NO_DATA;
576
        return NO_DATA;
553
    }
577
    }
554
    header = ( udp_header_ref ) data;
578
    header = ( udp_header_ref ) data;
-
 
579
 
555
    // set the source address
580
    // set the source address port
556
    address.sin_family = PF_INET;
-
 
557
    address.sin_port = ntohs( header->source );
-
 
558
    result = packet_get_addr( packet, & addr, NULL );
581
    result = packet_get_addr( packet, ( uint8_t ** ) & addr, NULL );
559
    if( result != sizeof( address.sin_addr.s_addr )){
582
    if( ERROR_OCCURRED( udp_set_address_port( addr, result, ntohs( header->source )))){
560
        pq_release( udp_globals.net_phone, packet_id );
583
        pq_release( udp_globals.net_phone, packet_id );
561
        return EINVAL;
584
        return ERROR_CODE;
562
    }
585
    }
563
    address.sin_addr.s_addr = *(( uint32_t * ) addr );
586
    * addrlen = ( size_t ) result;
564
    bzero( & address.sin_zero, sizeof( address.sin_zero ));
-
 
565
    // send the source address
587
    // send the source address
566
    ERROR_PROPAGATE( socket_write_data( & address, sizeof( address )));
588
    ERROR_PROPAGATE( socket_write_data( addr, * addrlen ));
-
 
589
 
567
    next_packet = pq_next( packet );
590
    next_packet = pq_next( packet );
568
    if( ! next_packet ){
591
    if( ! next_packet ){
569
        // write all if only one fragment
592
        // write all if only one fragment
570
        ERROR_PROPAGATE( socket_write_data( data + sizeof( udp_header_t ), packet_get_data_length( packet ) - sizeof( udp_header_t )));
593
        ERROR_PROPAGATE( socket_write_data( data + sizeof( udp_header_t ), packet_get_data_length( packet ) - sizeof( udp_header_t )));
571
        // store the total length
594
        // store the total length
Line 634... Line 657...
634
        return ERROR_CODE;
657
        return ERROR_CODE;
635
    }
658
    }
636
    return EOK;
659
    return EOK;
637
}
660
}
638
 
661
 
639
int socket_read_packet_data( packet_ref packet, size_t prefix, struct sockaddr_in * address_in ){
662
int socket_read_packet_data( packet_ref packet, size_t prefix, const struct sockaddr * addr, socklen_t addrlen ){
640
    ERROR_DECLARE;
663
    ERROR_DECLARE;
641
 
664
 
642
    ipc_callid_t    callid;
665
    ipc_callid_t    callid;
643
    size_t          length;
666
    size_t          length;
644
    void *          data;
667
    void *          data;
Line 655... Line 678...
655
        return ENOMEM;
678
        return ENOMEM;
656
    }
679
    }
657
    // read the data into the packet
680
    // read the data into the packet
658
    if( ERROR_OCCURRED( ipc_data_write_finalize( callid, data, length ))
681
    if( ERROR_OCCURRED( ipc_data_write_finalize( callid, data, length ))
659
    // set the packet destination address
682
    // set the packet destination address
660
    || ERROR_OCCURRED( packet_set_addr( * packet, NULL, ( uint8_t * ) & address_in->sin_addr.s_addr, sizeof( address_in->sin_addr.s_addr )))){
683
    || ERROR_OCCURRED( packet_set_addr( * packet, NULL, ( uint8_t * ) addr, addrlen ))){
661
        pq_release( udp_globals.net_phone, packet_get_id( * packet ));
684
        pq_release( udp_globals.net_phone, packet_get_id( * packet ));
662
        return ERROR_CODE;
685
        return ERROR_CODE;
663
    }
686
    }
664
    return ( int ) length;
687
    return ( int ) length;
665
}
688
}
Line 689... Line 712...
689
    }else{
712
    }else{
690
        udp_release_and_return( packet, EINVAL );
713
        udp_release_and_return( packet, EINVAL );
691
    }
714
    }
692
}
715
}
693
 
716
 
-
 
717
int udp_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port ){
-
 
718
    struct sockaddr_in *    address_in;
-
 
719
    struct sockaddr_in6 *   address_in6;
-
 
720
    size_t                  length;
-
 
721
 
-
 
722
    if( addrlen < 0 ) return EINVAL;
-
 
723
    length = ( size_t ) addrlen;
-
 
724
    if( length < sizeof( struct sockaddr )) return EINVAL;
-
 
725
    switch( addr->sa_family ){
-
 
726
        case AF_INET:
-
 
727
            if( length != sizeof( struct sockaddr_in )) return EINVAL;
-
 
728
            address_in = ( struct sockaddr_in * ) addr;
-
 
729
            address_in->sin_port = port;
-
 
730
            return EOK;
-
 
731
        case AF_INET6:
-
 
732
            if( length != sizeof( struct sockaddr_in6 )) return EINVAL;
-
 
733
            address_in6 = ( struct sockaddr_in6 * ) addr;
-
 
734
            address_in6->sin6_port = port;
-
 
735
            return EOK;
-
 
736
        default:
-
 
737
            return EAFNOSUPPORT;
-
 
738
    }
-
 
739
}
-
 
740
 
694
/** @}
741
/** @}
695
 */
742
 */