Rev 4578 | Rev 4603 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4578 | Rev 4589 | ||
|---|---|---|---|
| Line 39... | Line 39... | ||
| 39 | #include "../include/inet.h" |
39 | #include "../include/inet.h" |
| 40 | 40 | ||
| 41 | #include "../include/socket.h" |
41 | #include "../include/socket.h" |
| 42 | #include "../include/socket_errno.h" |
42 | #include "../include/socket_errno.h" |
| 43 | 43 | ||
| - | 44 | #include "../structures/dynamic_fifo.h" |
|
| 44 | #include "../structures/int_map.h" |
45 | #include "../structures/int_map.h" |
| 45 | #include "../structures/packet/packet.h" |
46 | #include "../structures/packet/packet.h" |
| 46 | #include "../structures/packet/packet_client.h" |
47 | #include "../structures/packet/packet_client.h" |
| 47 | 48 | ||
| 48 | #include "socket_core.h" |
49 | #include "socket_core.h" |
| Line 63... | Line 64... | ||
| 63 | address = ( struct sockaddr * ) addr; |
64 | address = ( struct sockaddr * ) addr; |
| 64 | switch( address->sa_family ){ |
65 | switch( address->sa_family ){ |
| 65 | case AF_INET: |
66 | case AF_INET: |
| 66 | if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
67 | if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
| 67 | address_in = ( struct sockaddr_in * ) addr; |
68 | address_in = ( struct sockaddr_in * ) addr; |
| - | 69 | // find the socket |
|
| 68 | socket = socket_cores_find( local_sockets, socket_id ); |
70 | socket = socket_cores_find( local_sockets, socket_id ); |
| 69 | if( ! socket ) return ENOTSOCK; |
71 | if( ! socket ) return ENOTSOCK; |
| - | 72 | // try to find the port |
|
| 70 | socket_pointer = socket_ports_find( global_sockets, address_in->sin_port ); |
73 | socket_pointer = socket_ports_find( global_sockets, address_in->sin_port ); |
| 71 | if( * socket_pointer ){ |
74 | if( socket_pointer ){ |
| - | 75 | // already used |
|
| 72 | return EADDRINUSE; |
76 | return EADDRINUSE; |
| 73 | } |
77 | } |
| - | 78 | // disbind if bound |
|
| 74 | socket_ports_exclude( global_sockets, socket->port ); |
79 | socket_ports_exclude( global_sockets, socket->port ); |
| - | 80 | // create a wrapper |
|
| 75 | socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer )); |
81 | socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer )); |
| 76 | if( ! socket_pointer ) return ENOMEM; |
82 | if( ! socket_pointer ) return ENOMEM; |
| 77 | * socket_pointer = socket; |
83 | * socket_pointer = socket; |
| - | 84 | // register the port |
|
| 78 | ERROR_PROPAGATE( socket_ports_add( global_sockets, address_in->sin_port, socket_pointer )); |
85 | ERROR_CODE = socket_ports_add( global_sockets, address_in->sin_port, socket_pointer ); |
| - | 86 | if( ERROR_CODE < 0 ){ |
|
| - | 87 | free( socket_pointer ); |
|
| - | 88 | } |
|
| 79 | socket->port = address_in->sin_port; |
89 | socket->port = address_in->sin_port; |
| 80 | break; |
90 | break; |
| 81 | // TODO IPv6 |
91 | // TODO IPv6 |
| 82 | default: |
92 | default: |
| 83 | return EAFNOSUPPORT; |
93 | return EAFNOSUPPORT; |
| 84 | } |
94 | } |
| 85 | return EOK; |
95 | return EOK; |
| 86 | } |
96 | } |
| 87 | 97 | ||
| 88 | int socket_create( socket_cores_ref local_sockets, int app_phone ){ |
98 | int socket_create( socket_cores_ref local_sockets, int app_phone, int * socket_id ){ |
| - | 99 | ERROR_DECLARE; |
|
| - | 100 | ||
| 89 | socket_core_ref socket; |
101 | socket_core_ref socket; |
| 90 | int res; |
102 | int res; |
| 91 | 103 | ||
| - | 104 | if( ! socket_id ) return EBADMEM; |
|
| 92 | socket = ( socket_core_ref ) malloc( sizeof( * socket )); |
105 | socket = ( socket_core_ref ) malloc( sizeof( * socket )); |
| 93 | if( ! socket ) return ENOMEM; |
106 | if( ! socket ) return ENOMEM; |
| - | 107 | // initialize |
|
| 94 | socket->phone = app_phone; |
108 | socket->phone = app_phone; |
| 95 | socket->port = -1; |
109 | socket->port = -1; |
| 96 | socket->device_id = -1; |
110 | socket->device_id = -1; |
| 97 | socket->peer_addr = NULL; |
111 | socket->peer_addr = NULL; |
| 98 | socket->connect_size = 2; |
- | |
| 99 | socket->receive_size = 8; |
- | |
| 100 | socket->connected = ( int * ) malloc( sizeof( int ) * socket->connect_size ); |
112 | if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->received, SOCKET_INITIAL_RECEIVED_SIZE ))){ |
| 101 | if( ! socket->connected ){ |
- | |
| 102 | free( socket ); |
113 | free( socket ); |
| 103 | return ENOMEM; |
114 | return ERROR_CODE; |
| 104 | } |
115 | } |
| 105 | bzero( socket->connected, sizeof( int ) * socket->connect_size ); |
- | |
| 106 | socket->received = ( int * ) malloc( sizeof( int ) * socket->receive_size ); |
116 | if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE ))){ |
| 107 | if( ! socket->received ){ |
117 | dyn_fifo_destroy( & socket->received ); |
| 108 | free( socket->connected ); |
- | |
| 109 | free( socket ); |
118 | free( socket ); |
| 110 | return ENOMEM; |
119 | return ERROR_CODE; |
| 111 | } |
120 | } |
| 112 | bzero( socket->received, sizeof( int ) * socket->receive_size ); |
121 | // get a next free socket number |
| 113 | socket->socket_id = socket_cores_count( local_sockets ) + 1; |
122 | socket->socket_id = socket_cores_count( local_sockets ) + 1; |
| - | 123 | // store the socket |
|
| 114 | res = socket_cores_add( local_sockets, socket->socket_id, socket ); |
124 | res = socket_cores_add( local_sockets, socket->socket_id, socket ); |
| 115 | if( res < 0 ){ |
125 | if( res < 0 ){ |
| 116 | free( socket->received ); |
126 | dyn_fifo_destroy( & socket->received ); |
| 117 | free( socket->connected ); |
127 | dyn_fifo_destroy( & socket->accepted ); |
| 118 | free( socket ); |
128 | free( socket ); |
| 119 | return res; |
129 | return res; |
| 120 | } |
130 | } |
| - | 131 | // return the socket identifier |
|
| 121 | return socket->socket_id; |
132 | * socket_id = socket->socket_id; |
| - | 133 | return EOK; |
|
| 122 | } |
134 | } |
| 123 | 135 | ||
| 124 | int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets ){ |
136 | int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets ){ |
| 125 | socket_core_ref socket; |
137 | socket_core_ref socket; |
| - | 138 | int accepted_id; |
|
| 126 | size_t i; |
139 | int packet_id; |
| 127 | 140 | ||
| - | 141 | // find the socket |
|
| 128 | socket = socket_cores_find( local_sockets, socket_id ); |
142 | socket = socket_cores_find( local_sockets, socket_id ); |
| 129 | if( ! socket ) return ENOTSOCK; |
143 | if( ! socket ) return ENOTSOCK; |
| 130 | socket_ports_exclude( global_sockets, socket->port ); |
144 | socket_ports_exclude( global_sockets, socket->port ); |
| 131 | if( socket->connected ){ |
145 | // destroy all accepted sockets |
| 132 | for( i = 0; i < socket->connect_size; ++ i ){ |
146 | while(( accepted_id = dyn_fifo_pop( & socket->accepted ))){ |
| 133 | if( socket->connected[ i ] ){ |
- | |
| 134 | socket_destroy( packet_phone, socket->connected[ i ], local_sockets, global_sockets ); |
147 | socket_destroy( packet_phone, accepted_id, local_sockets, global_sockets ); |
| 135 | } |
- | |
| 136 | } |
- | |
| 137 | } |
148 | } |
| 138 | if( socket->received ){ |
149 | // release all received packets |
| 139 | for( i = 0; i < socket->receive_size; ++ i ){ |
150 | while(( packet_id = dyn_fifo_pop( & socket->received ))){ |
| 140 | if( socket->received[ i ] ){ |
- | |
| 141 | pq_release( packet_phone, socket->received[ i ] ); |
151 | pq_release( packet_phone, packet_id ); |
| 142 | } |
- | |
| 143 | } |
- | |
| 144 | } |
152 | } |
| 145 | if( socket->connected ) free( socket->connected ); |
153 | dyn_fifo_destroy( & socket->received ); |
| 146 | if( socket->received ) free( socket->received ); |
154 | dyn_fifo_destroy( & socket->accepted ); |
| 147 | socket_cores_exclude( local_sockets, socket_id ); |
155 | socket_cores_exclude( local_sockets, socket_id ); |
| 148 | return EOK; |
156 | return EOK; |
| 149 | } |
157 | } |
| 150 | 158 | ||
| 151 | /** @} |
159 | /** @} |