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 ); |