Rev 4603 | Rev 4701 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4603 | Rev 4700 | ||
|---|---|---|---|
| Line 32... | Line 32... | ||
| 32 | 32 | ||
| 33 | /** @file |
33 | /** @file |
| 34 | */ |
34 | */ |
| 35 | 35 | ||
| 36 | #include <async.h> |
36 | #include <async.h> |
| - | 37 | #include <fibril_sync.h> |
|
| 37 | #include <malloc.h> |
38 | #include <malloc.h> |
| 38 | #include <stdio.h> |
39 | #include <stdio.h> |
| 39 | 40 | ||
| 40 | #include <ipc/ipc.h> |
41 | #include <ipc/ipc.h> |
| 41 | #include <ipc/services.h> |
42 | #include <ipc/services.h> |
| Line 64... | Line 65... | ||
| 64 | #include "udp_header.h" |
65 | #include "udp_header.h" |
| 65 | #include "udp_module.h" |
66 | #include "udp_module.h" |
| 66 | 67 | ||
| 67 | #define MAX_UDP_FRAGMENT_SIZE 65535 |
68 | #define MAX_UDP_FRAGMENT_SIZE 65535 |
| 68 | 69 | ||
| - | 70 | #define UDP_FREE_PORTS_START 1025 |
|
| - | 71 | #define UDP_FREE_PORTS_END 65535 |
|
| - | 72 | ||
| 69 | int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ); |
73 | int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ); |
| 70 | int udp_process_packet( packet_t packet ); |
74 | int udp_process_packet( packet_t packet ); |
| 71 | int process_client_messages( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ); |
75 | int process_client_messages( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ); |
| 72 | int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, void * addr, size_t addrlen, int fragments, int flags ); |
76 | int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, void * addr, size_t addrlen, int fragments, int flags ); |
| 73 | int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags ); |
77 | int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags ); |
| Line 80... | Line 84... | ||
| 80 | /** Initializes the module. |
84 | /** Initializes the module. |
| 81 | */ |
85 | */ |
| 82 | int udp_initialize( async_client_conn_t client_connection ){ |
86 | int udp_initialize( async_client_conn_t client_connection ){ |
| 83 | ERROR_DECLARE; |
87 | ERROR_DECLARE; |
| 84 | 88 | ||
| - | 89 | fibril_rwlock_initialize( & udp_globals.lock ); |
|
| - | 90 | fibril_rwlock_write_lock( & udp_globals.lock ); |
|
| 85 | udp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg ); |
91 | udp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg ); |
| 86 | if( udp_globals.ip_phone < 0 ){ |
92 | if( udp_globals.ip_phone < 0 ){ |
| 87 | return udp_globals.ip_phone; |
93 | return udp_globals.ip_phone; |
| 88 | } |
94 | } |
| 89 | ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix )); |
95 | ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix )); |
| 90 | ERROR_PROPAGATE( socket_ports_initialize( & udp_globals.sockets )); |
96 | ERROR_PROPAGATE( socket_ports_initialize( & udp_globals.sockets )); |
| 91 | udp_globals.prefix += sizeof( udp_header_t ); |
97 | udp_globals.prefix += sizeof( udp_header_t ); |
| 92 | udp_globals.content -= sizeof( udp_header_t ); |
98 | udp_globals.content -= sizeof( udp_header_t ); |
| - | 99 | udp_globals.last_used_port = UDP_FREE_PORTS_START - 1; |
|
| - | 100 | fibril_rwlock_write_unlock( & udp_globals.lock ); |
|
| 93 | return EOK; |
101 | return EOK; |
| 94 | } |
102 | } |
| 95 | 103 | ||
| 96 | int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ){ |
104 | int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ){ |
| 97 | ERROR_DECLARE; |
105 | ERROR_DECLARE; |
| Line 181... | Line 189... | ||
| 181 | packet_t packet; |
189 | packet_t packet; |
| 182 | 190 | ||
| 183 | * answer_count = 0; |
191 | * answer_count = 0; |
| 184 | switch( IPC_GET_METHOD( * call )){ |
192 | switch( IPC_GET_METHOD( * call )){ |
| 185 | case NET_TL_RECEIVED: |
193 | case NET_TL_RECEIVED: |
| - | 194 | fibril_rwlock_read_lock( & udp_globals.lock ); |
|
| 186 | ERROR_PROPAGATE( packet_translate( udp_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
195 | if( ! ERROR_OCCURRED( packet_translate( udp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){ |
| 187 | return udp_received_msg( IPC_GET_DEVICE( call ), packet, 0 ); |
196 | ERROR_CODE = udp_received_msg( IPC_GET_DEVICE( call ), packet, 0 ); |
| - | 197 | } |
|
| - | 198 | fibril_rwlock_read_unlock( & udp_globals.lock ); |
|
| - | 199 | return ERROR_CODE; |
|
| 188 | case IPC_M_CONNECT_TO_ME: |
200 | case IPC_M_CONNECT_TO_ME: |
| 189 | return process_client_messages( callid, call, answer, answer_count ); |
201 | return process_client_messages( callid, call, answer, answer_count ); |
| 190 | } |
202 | } |
| 191 | return ENOTSUP; |
203 | return ENOTSUP; |
| 192 | } |
204 | } |
| Line 198... | Line 210... | ||
| 198 | bool keep_on_going = true; |
210 | bool keep_on_going = true; |
| 199 | socket_cores_t local_sockets; |
211 | socket_cores_t local_sockets; |
| 200 | int app_phone = IPC_GET_PHONE( call ); |
212 | int app_phone = IPC_GET_PHONE( call ); |
| 201 | void * addr; |
213 | void * addr; |
| 202 | size_t addrlen; |
214 | size_t addrlen; |
| - | 215 | fibril_rwlock_t lock; |
|
| 203 | 216 | ||
| 204 | /* |
217 | /* |
| 205 | * Accept the connection |
218 | * Accept the connection |
| 206 | * - Answer the first IPC_M_CONNECT_ME_TO call. |
219 | * - Answer the first IPC_M_CONNECT_ME_TO call. |
| 207 | */ |
220 | */ |
| 208 | ipc_answer_0( callid, EOK ); |
221 | ipc_answer_0( callid, EOK ); |
| 209 | 222 | ||
| 210 | socket_cores_initialize( & local_sockets ); |
223 | socket_cores_initialize( & local_sockets ); |
| - | 224 | fibril_rwlock_initialize( & lock ); |
|
| 211 | 225 | ||
| 212 | while( keep_on_going ){ |
226 | while( keep_on_going ){ |
| 213 | // refresh data |
227 | // refresh data |
| 214 | * answer_count = 0; |
228 | * answer_count = 0; |
| 215 | IPC_SET_RETVAL( * answer, 0 ); |
229 | IPC_SET_RETVAL( * answer, 0 ); |
| Line 228... | Line 242... | ||
| 228 | case IPC_M_PHONE_HUNGUP: |
242 | case IPC_M_PHONE_HUNGUP: |
| 229 | keep_on_going = false; |
243 | keep_on_going = false; |
| 230 | res = EOK; |
244 | res = EOK; |
| 231 | break; |
245 | break; |
| 232 | case NET_SOCKET: |
246 | case NET_SOCKET: |
| - | 247 | fibril_rwlock_write_lock( & lock ); |
|
| 233 | res = socket_create( & local_sockets, app_phone, SOCKET_SET_SOCKET_ID( answer )); |
248 | res = socket_create( & local_sockets, app_phone, SOCKET_SET_SOCKET_ID( answer )); |
| - | 249 | fibril_rwlock_write_unlock( & lock ); |
|
| 234 | * SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t ); |
250 | * SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t ); |
| 235 | * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE; |
251 | * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE; |
| 236 | * answer_count = 3; |
252 | * answer_count = 3; |
| 237 | break; |
253 | break; |
| 238 | case NET_SOCKET_BIND: |
254 | case NET_SOCKET_BIND: |
| 239 | if( ERROR_OCCURRED( socket_read_data( & addr, & addrlen ))){ |
255 | if( ERROR_OCCURRED( socket_read_data( & addr, & addrlen ))){ |
| 240 | res = ERROR_CODE; |
256 | res = ERROR_CODE; |
| 241 | break; |
257 | break; |
| 242 | } |
258 | } |
| - | 259 | fibril_rwlock_write_lock( & lock ); |
|
| - | 260 | fibril_rwlock_write_lock( & udp_globals.lock ); |
|
| 243 | res = socket_bind( & local_sockets, & udp_globals.sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen ); |
261 | 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 ); |
| - | 262 | fibril_rwlock_write_unlock( & udp_globals.lock ); |
|
| - | 263 | fibril_rwlock_write_unlock( & lock ); |
|
| 244 | free( addr ); |
264 | free( addr ); |
| 245 | break; |
265 | break; |
| 246 | case NET_SOCKET_SENDTO: |
266 | case NET_SOCKET_SENDTO: |
| 247 | if( ERROR_OCCURRED( socket_read_data( & addr, & addrlen ))){ |
267 | if( ERROR_OCCURRED( socket_read_data( & addr, & addrlen ))){ |
| 248 | res = ERROR_CODE; |
268 | res = ERROR_CODE; |
| 249 | break; |
269 | break; |
| 250 | } |
270 | } |
| - | 271 | fibril_rwlock_read_lock( & lock ); |
|
| - | 272 | fibril_rwlock_read_lock( & udp_globals.lock ); |
|
| 251 | res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_FLAGS( call )); |
273 | res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_FLAGS( call )); |
| - | 274 | fibril_rwlock_read_unlock( & udp_globals.lock ); |
|
| - | 275 | fibril_rwlock_read_unlock( & lock ); |
|
| 252 | free( addr ); |
276 | free( addr ); |
| 253 | break; |
277 | break; |
| 254 | case NET_SOCKET_RECVFROM: |
278 | case NET_SOCKET_RECVFROM: |
| - | 279 | fibril_rwlock_read_lock( & lock ); |
|
| - | 280 | fibril_rwlock_read_lock( & udp_globals.lock ); |
|
| 255 | res = udp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call )); |
281 | res = udp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call )); |
| - | 282 | fibril_rwlock_read_unlock( & udp_globals.lock ); |
|
| - | 283 | fibril_rwlock_read_unlock( & lock ); |
|
| 256 | if( res > 0 ){ |
284 | if( res > 0 ){ |
| 257 | * SOCKET_SET_READ_DATA_LENGTH( answer ) = res; |
285 | * SOCKET_SET_READ_DATA_LENGTH( answer ) = res; |
| 258 | * SOCKET_SET_ADDRESS_LENGTH( answer ) = sizeof( struct sockaddr_in ); |
286 | * SOCKET_SET_ADDRESS_LENGTH( answer ) = sizeof( struct sockaddr_in ); |
| 259 | * answer_count = 2; |
287 | * answer_count = 2; |
| 260 | res = EOK; |
288 | res = EOK; |
| 261 | } |
289 | } |
| 262 | break; |
290 | break; |
| 263 | case NET_SOCKET_CLOSE: |
291 | case NET_SOCKET_CLOSE: |
| - | 292 | fibril_rwlock_write_lock( & lock ); |
|
| - | 293 | fibril_rwlock_write_lock( & udp_globals.lock ); |
|
| 264 | res = socket_destroy( udp_globals.net_phone, SOCKET_GET_SOCKET_ID( call ), & local_sockets, & udp_globals.sockets ); |
294 | res = socket_destroy( udp_globals.net_phone, SOCKET_GET_SOCKET_ID( call ), & local_sockets, & udp_globals.sockets ); |
| - | 295 | fibril_rwlock_write_unlock( & udp_globals.lock ); |
|
| - | 296 | fibril_rwlock_write_unlock( & lock ); |
|
| 265 | break; |
297 | break; |
| 266 | case NET_SOCKET_GETSOCKOPT: |
298 | case NET_SOCKET_GETSOCKOPT: |
| 267 | case NET_SOCKET_SETSOCKOPT: |
299 | case NET_SOCKET_SETSOCKOPT: |
| 268 | default: |
300 | default: |
| 269 | res = ENOTSUP; |
301 | res = ENOTSUP; |
| Line 313... | Line 345... | ||
| 313 | if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
345 | if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
| 314 | address_in = ( struct sockaddr_in * ) addr; |
346 | address_in = ( struct sockaddr_in * ) addr; |
| 315 | socket = socket_cores_find( local_sockets, socket_id ); |
347 | socket = socket_cores_find( local_sockets, socket_id ); |
| 316 | if( ! socket ) return ENOTSOCK; |
348 | if( ! socket ) return ENOTSOCK; |
| 317 | 349 | ||
| - | 350 | // bind the socket to a random free port if not bound |
|
| - | 351 | if( socket->port <= 0 ){ |
|
| - | 352 | // try to find a free port |
|
| - | 353 | fibril_rwlock_read_unlock( & udp_globals.lock ); |
|
| - | 354 | fibril_rwlock_write_lock( & udp_globals.lock ); |
|
| - | 355 | ERROR_PROPAGATE( socket_bind_free_port( & udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port )); |
|
| - | 356 | fibril_rwlock_write_unlock( & udp_globals.lock ); |
|
| - | 357 | fibril_rwlock_read_lock( & udp_globals.lock ); |
|
| - | 358 | // set the next port as the search starting port number |
|
| - | 359 | udp_globals.last_used_port = socket->port; |
|
| - | 360 | } |
|
| 318 | // TODO do not ask all the time |
361 | // TODO do not ask all the time |
| 319 | ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix )); |
362 | ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix )); |
| 320 | 363 | ||
| 321 | // read the first packet fragment |
364 | // read the first packet fragment |
| 322 | total_length = socket_read_packet_data( & packet, sizeof( udp_header_t ), address_in ); |
365 | total_length = socket_read_packet_data( & packet, sizeof( udp_header_t ), address_in ); |