Changeset aadf01e in mainline for uspace/srv/net/socket
- Timestamp:
- 2010-03-07T15:13:28Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 936835e
- Parents:
- aa85487
- Location:
- uspace/srv/net/socket
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/socket/socket_client.c
raa85487 raadf01e 75 75 /** Default timeout for connections in microseconds. 76 76 */ 77 #define SOCKET_CONNECT_TIMEOUT ( 1 * 1000 * 1000)77 #define SOCKET_CONNECT_TIMEOUT (1 * 1000 * 1000) 78 78 79 79 /** Maximum number of random attempts to find a new socket identifier before switching to the sequence. … … 97 97 /** Socket identifier. 98 98 */ 99 int 99 int socket_id; 100 100 /** Parent module phone. 101 101 */ 102 int 102 int phone; 103 103 /** Parent module service. 104 104 */ 105 services_t 105 services_t service; 106 106 /** Underlying protocol header size. 107 107 * Sending and receiving optimalization. 108 108 */ 109 size_t 109 size_t header_size; 110 110 /** Packet data fragment size. 111 111 * Sending optimalization. 112 112 */ 113 size_t 113 size_t data_fragment_size; 114 114 /** Sending safety lock. 115 115 * Locks the header_size and data_fragment_size attributes. 116 116 */ 117 fibril_rwlock_t 117 fibril_rwlock_t sending_lock; 118 118 /** Received packets queue. 119 119 */ 120 dyn_fifo_t 120 dyn_fifo_t received; 121 121 /** Received packets safety lock. 122 122 * Used for receiving and receive notifications. 123 123 * Locks the received attribute. 124 124 */ 125 fibril_mutex_t 125 fibril_mutex_t receive_lock; 126 126 /** Received packets signaling. 127 127 * Signaled upon receive notification. 128 128 */ 129 fibril_condvar_t 129 fibril_condvar_t receive_signal; 130 130 /** Waiting sockets queue. 131 131 */ 132 dyn_fifo_t 132 dyn_fifo_t accepted; 133 133 /** Waiting sockets safety lock. 134 134 * Used for accepting and accept notifications. 135 135 * Locks the accepted attribute. 136 136 */ 137 fibril_mutex_t 137 fibril_mutex_t accept_lock; 138 138 /** Waiting sockets signaling. 139 139 * Signaled upon accept notification. 140 140 */ 141 fibril_condvar_t 141 fibril_condvar_t accept_signal; 142 142 /** The number of blocked functions called. 143 143 * Used while waiting for the received packets or accepted sockets. 144 144 */ 145 int 145 int blocked; 146 146 }; 147 147 … … 150 150 * @see int_map.h 151 151 */ 152 INT_MAP_DECLARE( sockets, socket_t);152 INT_MAP_DECLARE(sockets, socket_t); 153 153 154 154 /** Socket client library global data. … … 157 157 /** TCP module phone. 158 158 */ 159 int 159 int tcp_phone; 160 160 /** UDP module phone. 161 161 */ 162 int 162 int udp_phone; 163 163 // /** The last socket identifier. 164 164 // */ … … 166 166 /** Active sockets. 167 167 */ 168 sockets_ref 168 sockets_ref sockets; 169 169 /** Safety lock. 170 170 * Write lock is used only for adding or removing sockets. … … 173 173 * No socket lock may be locked if this lock is unlocked. 174 174 */ 175 fibril_rwlock_t 175 fibril_rwlock_t lock; 176 176 } socket_globals = { 177 177 .tcp_phone = -1, … … 183 183 .writers = 0, 184 184 .waiters = { 185 .prev = & 186 .next = & 185 .prev = &socket_globals.lock.waiters, 186 .next = &socket_globals.lock.waiters 187 187 } 188 188 } 189 189 }; 190 190 191 INT_MAP_IMPLEMENT( sockets, socket_t);191 INT_MAP_IMPLEMENT(sockets, socket_t); 192 192 193 193 /** Returns the TCP module phone. … … 196 196 * @returns Other error codes as defined for the bind_service_timeout() function. 197 197 */ 198 static int socket_get_tcp_phone( void);198 static int socket_get_tcp_phone(void); 199 199 200 200 /** Returns the UDP module phone. … … 203 203 * @returns Other error codes as defined for the bind_service_timeout() function. 204 204 */ 205 static int socket_get_udp_phone( void);205 static int socket_get_udp_phone(void); 206 206 207 207 /** Returns the active sockets. 208 208 * @returns The active sockets. 209 209 */ 210 static sockets_ref socket_get_sockets( void);210 static sockets_ref socket_get_sockets(void); 211 211 212 212 /** Tries to find a new free socket identifier. … … 214 214 * @returns ELIMIT if there is no socket identifier available. 215 215 */ 216 static int socket_generate_new_id( void);216 static int socket_generate_new_id(void); 217 217 218 218 /** Default thread for new connections. … … 220 220 * @param[in] icall The initial message call structure. 221 221 */ 222 void socket_connection( ipc_callid_t iid, ipc_call_t * icall);222 void socket_connection(ipc_callid_t iid, ipc_call_t * icall); 223 223 224 224 /** Sends message to the socket parent module with specified data. … … 234 234 * @returns Other error codes as defined for the spcific message. 235 235 */ 236 int socket_send_data( int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength);236 int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength); 237 237 238 238 /** Initializes a new socket specific data. … … 242 242 * @param[in] service The parent module service. 243 243 */ 244 void socket_initialize( socket_ref socket, int socket_id, int phone, services_t service);244 void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service); 245 245 246 246 /** Clears and destroys the socket. 247 247 * @param[in] socket The socket to be destroyed. 248 248 */ 249 void socket_destroy( socket_ref socket);249 void socket_destroy(socket_ref socket); 250 250 251 251 /** Receives data via the socket. … … 263 263 * @returns Other error codes as defined for the spcific message. 264 264 */ 265 int recvfrom_core( ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen);265 int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen); 266 266 267 267 /** Sends data via the socket to the remote address. … … 280 280 * @returns Other error codes as defined for the NET_SOCKET_SENDTO message. 281 281 */ 282 int sendto_core( ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen);283 284 static int socket_get_tcp_phone( void){285 if( socket_globals.tcp_phone < 0){286 socket_globals.tcp_phone = bind_service_timeout( SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT);282 int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen); 283 284 static int socket_get_tcp_phone(void){ 285 if(socket_globals.tcp_phone < 0){ 286 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT); 287 287 } 288 288 return socket_globals.tcp_phone; 289 289 } 290 290 291 static int socket_get_udp_phone( void){292 if( socket_globals.udp_phone < 0){293 socket_globals.udp_phone = bind_service_timeout( SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT);291 static int socket_get_udp_phone(void){ 292 if(socket_globals.udp_phone < 0){ 293 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT); 294 294 } 295 295 return socket_globals.udp_phone; 296 296 } 297 297 298 static sockets_ref socket_get_sockets( void ){ 299 if( ! socket_globals.sockets ){ 300 socket_globals.sockets = ( sockets_ref ) malloc( sizeof( sockets_t )); 301 if( ! socket_globals.sockets ) return NULL; 302 if( sockets_initialize( socket_globals.sockets ) != EOK ){ 303 free( socket_globals.sockets ); 298 static sockets_ref socket_get_sockets(void){ 299 if(! socket_globals.sockets){ 300 socket_globals.sockets = (sockets_ref) malloc(sizeof(sockets_t)); 301 if(! socket_globals.sockets){ 302 return NULL; 303 } 304 if(sockets_initialize(socket_globals.sockets) != EOK){ 305 free(socket_globals.sockets); 304 306 socket_globals.sockets = NULL; 305 307 } 306 srand( 308 srand(task_get_id()); 307 309 } 308 310 return socket_globals.sockets; 309 311 } 310 312 311 static int socket_generate_new_id( void){312 sockets_ref 313 int 314 int 313 static int socket_generate_new_id(void){ 314 sockets_ref sockets; 315 int socket_id; 316 int count; 315 317 316 318 sockets = socket_get_sockets(); … … 318 320 // socket_id = socket_globals.last_id; 319 321 do{ 320 if( count < SOCKET_ID_TRIES){322 if(count < SOCKET_ID_TRIES){ 321 323 socket_id = rand() % INT_MAX; 322 324 ++ count; 323 }else if( count == SOCKET_ID_TRIES){325 }else if(count == SOCKET_ID_TRIES){ 324 326 socket_id = 1; 325 327 ++ count; 326 328 // only this branch for last_id 327 329 }else{ 328 if( socket_id < INT_MAX){330 if(socket_id < INT_MAX){ 329 331 ++ socket_id; 330 /* }else if( socket_globals.last_id){332 /* }else if(socket_globals.last_id){ 331 333 * socket_globals.last_id = 0; 332 334 * socket_id = 1; … … 335 337 } 336 338 } 337 }while( sockets_find( sockets, socket_id));339 }while(sockets_find(sockets, socket_id)); 338 340 // last_id = socket_id 339 341 return socket_id; 340 342 } 341 343 342 void socket_initialize( socket_ref socket, int socket_id, int phone, services_t service){344 void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service){ 343 345 socket->socket_id = socket_id; 344 346 socket->phone = phone; 345 347 socket->service = service; 346 dyn_fifo_initialize( & socket->received, SOCKET_INITIAL_RECEIVED_SIZE);347 dyn_fifo_initialize( & socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);348 fibril_mutex_initialize( & socket->receive_lock);349 fibril_condvar_initialize( & socket->receive_signal);350 fibril_mutex_initialize( & socket->accept_lock);351 fibril_condvar_initialize( & socket->accept_signal);352 fibril_rwlock_initialize( & socket->sending_lock);353 } 354 355 void socket_connection( ipc_callid_t iid, ipc_call_t * icall){348 dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE); 349 dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE); 350 fibril_mutex_initialize(&socket->receive_lock); 351 fibril_condvar_initialize(&socket->receive_signal); 352 fibril_mutex_initialize(&socket->accept_lock); 353 fibril_condvar_initialize(&socket->accept_signal); 354 fibril_rwlock_initialize(&socket->sending_lock); 355 } 356 357 void socket_connection(ipc_callid_t iid, ipc_call_t * icall){ 356 358 ERROR_DECLARE; 357 359 358 ipc_callid_t 359 ipc_call_t 360 socket_ref 361 362 while( true){363 364 callid = async_get_call( & call);365 switch( IPC_GET_METHOD( call)){360 ipc_callid_t callid; 361 ipc_call_t call; 362 socket_ref socket; 363 364 while(true){ 365 366 callid = async_get_call(&call); 367 switch(IPC_GET_METHOD(call)){ 366 368 case NET_SOCKET_RECEIVED: 367 369 case NET_SOCKET_ACCEPTED: 368 370 case NET_SOCKET_DATA_FRAGMENT_SIZE: 369 fibril_rwlock_read_lock( & socket_globals.lock);371 fibril_rwlock_read_lock(&socket_globals.lock); 370 372 // find the socket 371 socket = sockets_find( socket_get_sockets(), SOCKET_GET_SOCKET_ID( call));372 if( ! socket){373 socket = sockets_find(socket_get_sockets(), SOCKET_GET_SOCKET_ID(call)); 374 if(! socket){ 373 375 ERROR_CODE = ENOTSOCK; 374 376 }else{ 375 switch( IPC_GET_METHOD( call)){377 switch(IPC_GET_METHOD(call)){ 376 378 case NET_SOCKET_RECEIVED: 377 fibril_mutex_lock( & socket->receive_lock);379 fibril_mutex_lock(&socket->receive_lock); 378 380 // push the number of received packet fragments 379 if( ! ERROR_OCCURRED( dyn_fifo_push( & socket->received, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_MAX_RECEIVED_SIZE))){381 if(! ERROR_OCCURRED(dyn_fifo_push(&socket->received, SOCKET_GET_DATA_FRAGMENTS(call), SOCKET_MAX_RECEIVED_SIZE))){ 380 382 // signal the received packet 381 fibril_condvar_signal( & socket->receive_signal);383 fibril_condvar_signal(&socket->receive_signal); 382 384 } 383 fibril_mutex_unlock( & socket->receive_lock);385 fibril_mutex_unlock(&socket->receive_lock); 384 386 break; 385 387 case NET_SOCKET_ACCEPTED: 386 388 // push the new socket identifier 387 fibril_mutex_lock( & socket->accept_lock);388 if( ! ERROR_OCCURRED( dyn_fifo_push( & socket->accepted, 1, SOCKET_MAX_ACCEPTED_SIZE))){389 fibril_mutex_lock(&socket->accept_lock); 390 if(! ERROR_OCCURRED(dyn_fifo_push(&socket->accepted, 1, SOCKET_MAX_ACCEPTED_SIZE))){ 389 391 // signal the accepted socket 390 fibril_condvar_signal( & socket->accept_signal);392 fibril_condvar_signal(&socket->accept_signal); 391 393 } 392 fibril_mutex_unlock( & socket->accept_lock);394 fibril_mutex_unlock(&socket->accept_lock); 393 395 break; 394 396 default: 395 397 ERROR_CODE = ENOTSUP; 396 398 } 397 if(( SOCKET_GET_DATA_FRAGMENT_SIZE( call ) > 0)398 && ( SOCKET_GET_DATA_FRAGMENT_SIZE( call ) != socket->data_fragment_size)){399 fibril_rwlock_write_lock( & socket->sending_lock);399 if((SOCKET_GET_DATA_FRAGMENT_SIZE(call) > 0) 400 && (SOCKET_GET_DATA_FRAGMENT_SIZE(call) != socket->data_fragment_size)){ 401 fibril_rwlock_write_lock(&socket->sending_lock); 400 402 // set the data fragment size 401 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( call);402 fibril_rwlock_write_unlock( & socket->sending_lock);403 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(call); 404 fibril_rwlock_write_unlock(&socket->sending_lock); 403 405 } 404 406 } 405 fibril_rwlock_read_unlock( & socket_globals.lock);407 fibril_rwlock_read_unlock(&socket_globals.lock); 406 408 break; 407 409 default: 408 410 ERROR_CODE = ENOTSUP; 409 411 } 410 ipc_answer_0( callid, ( ipcarg_t ) ERROR_CODE);411 } 412 } 413 414 int socket( int domain, int type, int protocol){412 ipc_answer_0(callid, (ipcarg_t) ERROR_CODE); 413 } 414 } 415 416 int socket(int domain, int type, int protocol){ 415 417 ERROR_DECLARE; 416 418 417 socket_ref 418 int 419 int 420 services_t 419 socket_ref socket; 420 int phone; 421 int socket_id; 422 services_t service; 421 423 422 424 // find the appropriate service 423 switch( domain){425 switch(domain){ 424 426 case PF_INET: 425 switch( type){427 switch(type){ 426 428 case SOCK_STREAM: 427 if( ! protocol ) protocol = IPPROTO_TCP; 428 switch( protocol ){ 429 if(! protocol){ 430 protocol = IPPROTO_TCP; 431 } 432 switch(protocol){ 429 433 case IPPROTO_TCP: 430 434 phone = socket_get_tcp_phone(); … … 436 440 break; 437 441 case SOCK_DGRAM: 438 if( ! protocol ) protocol = IPPROTO_UDP; 439 switch( protocol ){ 442 if(! protocol){ 443 protocol = IPPROTO_UDP; 444 } 445 switch(protocol){ 440 446 case IPPROTO_UDP: 441 447 phone = socket_get_udp_phone(); … … 455 461 return EPFNOSUPPORT; 456 462 } 457 if( phone < 0 ) return phone; 463 if(phone < 0){ 464 return phone; 465 } 458 466 // create a new socket structure 459 socket = ( socket_ref ) malloc( sizeof( socket_t )); 460 if( ! socket ) return ENOMEM; 461 bzero( socket, sizeof( * socket )); 462 fibril_rwlock_write_lock( & socket_globals.lock ); 467 socket = (socket_ref) malloc(sizeof(socket_t)); 468 if(! socket){ 469 return ENOMEM; 470 } 471 bzero(socket, sizeof(*socket)); 472 fibril_rwlock_write_lock(&socket_globals.lock); 463 473 // request a new socket 464 474 socket_id = socket_generate_new_id(); 465 if( socket_id <= 0){466 fibril_rwlock_write_unlock( & socket_globals.lock);467 free( socket);475 if(socket_id <= 0){ 476 fibril_rwlock_write_unlock(&socket_globals.lock); 477 free(socket); 468 478 return socket_id; 469 479 } 470 if( ERROR_OCCURRED(( int ) async_req_3_3( phone, NET_SOCKET, socket_id, 0, service, NULL, ( ipcarg_t * ) & socket->data_fragment_size, ( ipcarg_t * ) & socket->header_size))){471 fibril_rwlock_write_unlock( & socket_globals.lock);472 free( socket);480 if(ERROR_OCCURRED((int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL, (ipcarg_t *) &socket->data_fragment_size, (ipcarg_t *) &socket->header_size))){ 481 fibril_rwlock_write_unlock(&socket_globals.lock); 482 free(socket); 473 483 return ERROR_CODE; 474 484 } 475 485 // finish the new socket initialization 476 socket_initialize( socket, socket_id, phone, service);486 socket_initialize(socket, socket_id, phone, service); 477 487 // store the new socket 478 ERROR_CODE = sockets_add( socket_get_sockets(), socket_id, socket);479 fibril_rwlock_write_unlock( & socket_globals.lock);480 if( ERROR_CODE < 0){481 dyn_fifo_destroy( & socket->received);482 dyn_fifo_destroy( & socket->accepted);483 free( socket);484 async_msg_3( phone, NET_SOCKET_CLOSE, ( ipcarg_t ) socket_id, 0, service);488 ERROR_CODE = sockets_add(socket_get_sockets(), socket_id, socket); 489 fibril_rwlock_write_unlock(&socket_globals.lock); 490 if(ERROR_CODE < 0){ 491 dyn_fifo_destroy(&socket->received); 492 dyn_fifo_destroy(&socket->accepted); 493 free(socket); 494 async_msg_3(phone, NET_SOCKET_CLOSE, (ipcarg_t) socket_id, 0, service); 485 495 return ERROR_CODE; 486 496 } … … 489 499 } 490 500 491 int socket_send_data( int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength ){ 492 socket_ref socket; 493 aid_t message_id; 494 ipcarg_t result; 495 496 if( ! data ) return EBADMEM; 497 if( ! datalength ) return NO_DATA; 498 499 fibril_rwlock_read_lock( & socket_globals.lock ); 501 int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength){ 502 socket_ref socket; 503 aid_t message_id; 504 ipcarg_t result; 505 506 if(! data){ 507 return EBADMEM; 508 } 509 if(! datalength){ 510 return NO_DATA; 511 } 512 513 fibril_rwlock_read_lock(&socket_globals.lock); 500 514 // find the socket 501 socket = sockets_find( socket_get_sockets(), socket_id);502 if( ! socket){503 fibril_rwlock_read_unlock( & socket_globals.lock);515 socket = sockets_find(socket_get_sockets(), socket_id); 516 if(! socket){ 517 fibril_rwlock_read_unlock(&socket_globals.lock); 504 518 return ENOTSOCK; 505 519 } 506 520 // request the message 507 message_id = async_send_3( socket->phone, message, ( ipcarg_t ) socket->socket_id, arg2, socket->service, NULL);521 message_id = async_send_3(socket->phone, message, (ipcarg_t) socket->socket_id, arg2, socket->service, NULL); 508 522 // send the address 509 async_data_write_start( socket->phone, data, datalength ); 510 fibril_rwlock_read_unlock( & socket_globals.lock ); 511 async_wait_for( message_id, & result ); 512 return ( int ) result; 513 } 514 515 int bind( int socket_id, const struct sockaddr * my_addr, socklen_t addrlen ){ 516 if( addrlen <= 0 ) return EINVAL; 523 async_data_write_start(socket->phone, data, datalength); 524 fibril_rwlock_read_unlock(&socket_globals.lock); 525 async_wait_for(message_id, &result); 526 return (int) result; 527 } 528 529 int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen){ 530 if(addrlen <= 0){ 531 return EINVAL; 532 } 517 533 // send the address 518 return socket_send_data( socket_id, NET_SOCKET_BIND, 0, my_addr, ( size_t ) addrlen ); 519 } 520 521 int listen( int socket_id, int backlog ){ 522 socket_ref socket; 523 int result; 524 525 if( backlog <= 0 ) return EINVAL; 526 fibril_rwlock_read_lock( & socket_globals.lock ); 534 return socket_send_data(socket_id, NET_SOCKET_BIND, 0, my_addr, (size_t) addrlen); 535 } 536 537 int listen(int socket_id, int backlog){ 538 socket_ref socket; 539 int result; 540 541 if(backlog <= 0){ 542 return EINVAL; 543 } 544 fibril_rwlock_read_lock(&socket_globals.lock); 527 545 // find the socket 528 socket = sockets_find( socket_get_sockets(), socket_id);529 if( ! socket){530 fibril_rwlock_read_unlock( & socket_globals.lock);546 socket = sockets_find(socket_get_sockets(), socket_id); 547 if(! socket){ 548 fibril_rwlock_read_unlock(&socket_globals.lock); 531 549 return ENOTSOCK; 532 550 } 533 551 // request listen backlog change 534 result = ( int ) async_req_3_0( socket->phone, NET_SOCKET_LISTEN, ( ipcarg_t ) socket->socket_id, ( ipcarg_t ) backlog, socket->service);535 fibril_rwlock_read_unlock( & socket_globals.lock);552 result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN, (ipcarg_t) socket->socket_id, (ipcarg_t) backlog, socket->service); 553 fibril_rwlock_read_unlock(&socket_globals.lock); 536 554 return result; 537 555 } 538 556 539 int accept( int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen ){ 540 socket_ref socket; 541 socket_ref new_socket; 542 aid_t message_id; 543 ipcarg_t ipc_result; 544 int result; 545 ipc_call_t answer; 546 547 if(( ! cliaddr ) || ( ! addrlen )) return EBADMEM; 548 549 fibril_rwlock_write_lock( & socket_globals.lock ); 557 int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen){ 558 socket_ref socket; 559 socket_ref new_socket; 560 aid_t message_id; 561 ipcarg_t ipc_result; 562 int result; 563 ipc_call_t answer; 564 565 if((! cliaddr) || (! addrlen)){ 566 return EBADMEM; 567 } 568 569 fibril_rwlock_write_lock(&socket_globals.lock); 550 570 // find the socket 551 socket = sockets_find( socket_get_sockets(), socket_id);552 if( ! socket){553 fibril_rwlock_write_unlock( & socket_globals.lock);571 socket = sockets_find(socket_get_sockets(), socket_id); 572 if(! socket){ 573 fibril_rwlock_write_unlock(&socket_globals.lock); 554 574 return ENOTSOCK; 555 575 } 556 fibril_mutex_lock( & socket->accept_lock);576 fibril_mutex_lock(&socket->accept_lock); 557 577 // wait for an accepted socket 558 578 ++ socket->blocked; 559 while( dyn_fifo_value( & socket->accepted ) <= 0){560 fibril_rwlock_write_unlock( & socket_globals.lock);561 fibril_condvar_wait( & socket->accept_signal, & socket->accept_lock);562 fibril_rwlock_write_lock( & socket_globals.lock);579 while(dyn_fifo_value(&socket->accepted) <= 0){ 580 fibril_rwlock_write_unlock(&socket_globals.lock); 581 fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock); 582 fibril_rwlock_write_lock(&socket_globals.lock); 563 583 } 564 584 -- socket->blocked; 565 585 566 586 // create a new scoket 567 new_socket = ( socket_ref ) malloc( sizeof( socket_t));568 if( ! new_socket){569 fibril_mutex_unlock( & socket->accept_lock);570 fibril_rwlock_write_unlock( & socket_globals.lock);587 new_socket = (socket_ref) malloc(sizeof(socket_t)); 588 if(! new_socket){ 589 fibril_mutex_unlock(&socket->accept_lock); 590 fibril_rwlock_write_unlock(&socket_globals.lock); 571 591 return ENOMEM; 572 592 } 573 bzero( new_socket, sizeof( * new_socket));593 bzero(new_socket, sizeof(*new_socket)); 574 594 socket_id = socket_generate_new_id(); 575 if( socket_id <= 0){576 fibril_mutex_unlock( & socket->accept_lock);577 fibril_rwlock_write_unlock( & socket_globals.lock);578 free( new_socket);595 if(socket_id <= 0){ 596 fibril_mutex_unlock(&socket->accept_lock); 597 fibril_rwlock_write_unlock(&socket_globals.lock); 598 free(new_socket); 579 599 return socket_id; 580 600 } 581 socket_initialize( new_socket, socket_id, socket->phone, socket->service);582 result = sockets_add( socket_get_sockets(), new_socket->socket_id, new_socket);583 if( result < 0){584 fibril_mutex_unlock( & socket->accept_lock);585 fibril_rwlock_write_unlock( & socket_globals.lock);586 free( new_socket);601 socket_initialize(new_socket, socket_id, socket->phone, socket->service); 602 result = sockets_add(socket_get_sockets(), new_socket->socket_id, new_socket); 603 if(result < 0){ 604 fibril_mutex_unlock(&socket->accept_lock); 605 fibril_rwlock_write_unlock(&socket_globals.lock); 606 free(new_socket); 587 607 return result; 588 608 } 589 609 590 610 // request accept 591 message_id = async_send_5( socket->phone, NET_SOCKET_ACCEPT, ( ipcarg_t ) socket->socket_id, 0, socket->service, 0, new_socket->socket_id, & answer);611 message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT, (ipcarg_t) socket->socket_id, 0, socket->service, 0, new_socket->socket_id, &answer); 592 612 // read address 593 ipc_data_read_start( socket->phone, cliaddr, * addrlen);594 fibril_rwlock_write_unlock( & socket_globals.lock);595 async_wait_for( message_id, & ipc_result);613 ipc_data_read_start(socket->phone, cliaddr, * addrlen); 614 fibril_rwlock_write_unlock(&socket_globals.lock); 615 async_wait_for(message_id, &ipc_result); 596 616 result = (int) ipc_result; 597 if( result > 0){598 if( result != socket_id){617 if(result > 0){ 618 if(result != socket_id){ 599 619 result = EINVAL; 600 620 } 601 621 // dequeue the accepted socket if successful 602 dyn_fifo_pop( & socket->accepted);622 dyn_fifo_pop(&socket->accepted); 603 623 // set address length 604 * addrlen = SOCKET_GET_ADDRESS_LENGTH( answer);605 new_socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( answer);606 }else if( result == ENOTSOCK){624 *addrlen = SOCKET_GET_ADDRESS_LENGTH(answer); 625 new_socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(answer); 626 }else if(result == ENOTSOCK){ 607 627 // empty the queue if no accepted sockets 608 while( dyn_fifo_pop( & socket->accepted ) > 0);609 } 610 fibril_mutex_unlock( & socket->accept_lock);628 while(dyn_fifo_pop(&socket->accepted) > 0); 629 } 630 fibril_mutex_unlock(&socket->accept_lock); 611 631 return result; 612 632 } 613 633 614 int connect( int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen ){ 615 if( ! serv_addr ) return EDESTADDRREQ; 616 if( ! addrlen ) return EDESTADDRREQ; 634 int connect(int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen){ 635 if(! serv_addr){ 636 return EDESTADDRREQ; 637 } 638 if(! addrlen){ 639 return EDESTADDRREQ; 640 } 617 641 // send the address 618 return socket_send_data( socket_id, NET_SOCKET_CONNECT, 0, serv_addr, addrlen);619 } 620 621 int closesocket( int socket_id){642 return socket_send_data(socket_id, NET_SOCKET_CONNECT, 0, serv_addr, addrlen); 643 } 644 645 int closesocket(int socket_id){ 622 646 ERROR_DECLARE; 623 647 624 socket_ref 625 626 fibril_rwlock_write_lock( & socket_globals.lock);627 socket = sockets_find( socket_get_sockets(), socket_id);628 if( ! socket){629 fibril_rwlock_write_unlock( & socket_globals.lock);648 socket_ref socket; 649 650 fibril_rwlock_write_lock(&socket_globals.lock); 651 socket = sockets_find(socket_get_sockets(), socket_id); 652 if(! socket){ 653 fibril_rwlock_write_unlock(&socket_globals.lock); 630 654 return ENOTSOCK; 631 655 } 632 if( socket->blocked){633 fibril_rwlock_write_unlock( & socket_globals.lock);656 if(socket->blocked){ 657 fibril_rwlock_write_unlock(&socket_globals.lock); 634 658 return EINPROGRESS; 635 659 } 636 660 // request close 637 ERROR_PROPAGATE(( int ) async_req_3_0( socket->phone, NET_SOCKET_CLOSE, ( ipcarg_t ) socket->socket_id, 0, socket->service));661 ERROR_PROPAGATE((int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE, (ipcarg_t) socket->socket_id, 0, socket->service)); 638 662 // free the socket structure 639 socket_destroy( socket);640 fibril_rwlock_write_unlock( & socket_globals.lock);663 socket_destroy(socket); 664 fibril_rwlock_write_unlock(&socket_globals.lock); 641 665 return EOK; 642 666 } 643 667 644 void socket_destroy( socket_ref socket){645 int 668 void socket_destroy(socket_ref socket){ 669 int accepted_id; 646 670 647 671 // destroy all accepted sockets 648 while(( accepted_id = dyn_fifo_pop( & socket->accepted )) >= 0){649 socket_destroy( sockets_find( socket_get_sockets(), accepted_id));650 } 651 dyn_fifo_destroy( & socket->received);652 dyn_fifo_destroy( & socket->accepted);653 sockets_exclude( socket_get_sockets(), socket->socket_id);654 } 655 656 int send( int socket_id, void * data, size_t datalength, int flags){672 while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){ 673 socket_destroy(sockets_find(socket_get_sockets(), accepted_id)); 674 } 675 dyn_fifo_destroy(&socket->received); 676 dyn_fifo_destroy(&socket->accepted); 677 sockets_exclude(socket_get_sockets(), socket->socket_id); 678 } 679 680 int send(int socket_id, void * data, size_t datalength, int flags){ 657 681 // without the address 658 return sendto_core( NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0 ); 659 } 660 661 int sendto( int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen ){ 662 if( ! toaddr ) return EDESTADDRREQ; 663 if( ! addrlen ) return EDESTADDRREQ; 682 return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0); 683 } 684 685 int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){ 686 if(! toaddr){ 687 return EDESTADDRREQ; 688 } 689 if(! addrlen){ 690 return EDESTADDRREQ; 691 } 664 692 // with the address 665 return sendto_core( NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen ); 666 } 667 668 int sendto_core( ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen ){ 669 socket_ref socket; 670 aid_t message_id; 671 ipcarg_t result; 672 size_t fragments; 673 ipc_call_t answer; 674 675 if( ! data ) return EBADMEM; 676 if( ! datalength ) return NO_DATA; 677 fibril_rwlock_read_lock( & socket_globals.lock ); 693 return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen); 694 } 695 696 int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){ 697 socket_ref socket; 698 aid_t message_id; 699 ipcarg_t result; 700 size_t fragments; 701 ipc_call_t answer; 702 703 if(! data){ 704 return EBADMEM; 705 } 706 if(! datalength){ 707 return NO_DATA; 708 } 709 fibril_rwlock_read_lock(&socket_globals.lock); 678 710 // find socket 679 socket = sockets_find( socket_get_sockets(), socket_id);680 if( ! socket){681 fibril_rwlock_read_unlock( & socket_globals.lock);711 socket = sockets_find(socket_get_sockets(), socket_id); 712 if(! socket){ 713 fibril_rwlock_read_unlock(&socket_globals.lock); 682 714 return ENOTSOCK; 683 715 } 684 fibril_rwlock_read_lock( & socket->sending_lock);716 fibril_rwlock_read_lock(&socket->sending_lock); 685 717 // compute data fragment count 686 if( socket->data_fragment_size > 0){687 fragments = ( datalength + socket->header_size) / socket->data_fragment_size;688 if(( datalength + socket->header_size ) % socket->data_fragment_size) ++ fragments;718 if(socket->data_fragment_size > 0){ 719 fragments = (datalength + socket->header_size) / socket->data_fragment_size; 720 if((datalength + socket->header_size) % socket->data_fragment_size) ++ fragments; 689 721 }else{ 690 722 fragments = 1; 691 723 } 692 724 // request send 693 message_id = async_send_5( socket->phone, message, ( ipcarg_t ) socket->socket_id, ( fragments == 1 ? datalength : socket->data_fragment_size ), socket->service, ( ipcarg_t ) flags, fragments, & answer);725 message_id = async_send_5(socket->phone, message, (ipcarg_t) socket->socket_id, (fragments == 1 ? datalength : socket->data_fragment_size), socket->service, (ipcarg_t) flags, fragments, &answer); 694 726 // send the address if given 695 if(( ! toaddr ) || ( async_data_write_start( socket->phone, toaddr, addrlen ) == EOK)){696 if( fragments == 1){727 if((! toaddr) || (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)){ 728 if(fragments == 1){ 697 729 // send all if only one fragment 698 async_data_write_start( socket->phone, data, datalength);730 async_data_write_start(socket->phone, data, datalength); 699 731 }else{ 700 732 // send the first fragment 701 async_data_write_start( socket->phone, data, socket->data_fragment_size - socket->header_size);702 data = (( const uint8_t * ) data) + socket->data_fragment_size - socket->header_size;733 async_data_write_start(socket->phone, data, socket->data_fragment_size - socket->header_size); 734 data = ((const uint8_t *) data) + socket->data_fragment_size - socket->header_size; 703 735 // send the middle fragments 704 while(( -- fragments ) > 1){705 async_data_write_start( socket->phone, data, socket->data_fragment_size);706 data = (( const uint8_t * ) data) + socket->data_fragment_size;736 while((-- fragments) > 1){ 737 async_data_write_start(socket->phone, data, socket->data_fragment_size); 738 data = ((const uint8_t *) data) + socket->data_fragment_size; 707 739 } 708 740 // send the last fragment 709 async_data_write_start( socket->phone, data, ( datalength + socket->header_size ) % socket->data_fragment_size);710 } 711 } 712 async_wait_for( message_id, & result);713 if(( SOCKET_GET_DATA_FRAGMENT_SIZE( answer ) > 0)714 && ( SOCKET_GET_DATA_FRAGMENT_SIZE( answer ) != socket->data_fragment_size)){741 async_data_write_start(socket->phone, data, (datalength + socket->header_size) % socket->data_fragment_size); 742 } 743 } 744 async_wait_for(message_id, &result); 745 if((SOCKET_GET_DATA_FRAGMENT_SIZE(answer) > 0) 746 && (SOCKET_GET_DATA_FRAGMENT_SIZE(answer) != socket->data_fragment_size)){ 715 747 // set the data fragment size 716 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( answer);717 } 718 fibril_rwlock_read_unlock( & socket->sending_lock);719 fibril_rwlock_read_unlock( & socket_globals.lock);720 return ( int) result;721 } 722 723 int recv( int socket_id, void * data, size_t datalength, int flags){748 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(answer); 749 } 750 fibril_rwlock_read_unlock(&socket->sending_lock); 751 fibril_rwlock_read_unlock(&socket_globals.lock); 752 return (int) result; 753 } 754 755 int recv(int socket_id, void * data, size_t datalength, int flags){ 724 756 // without the address 725 return recvfrom_core( NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL ); 726 } 727 728 int recvfrom( int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen ){ 729 if( ! fromaddr ) return EBADMEM; 730 if( ! addrlen ) return NO_DATA; 757 return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL); 758 } 759 760 int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){ 761 if(! fromaddr){ 762 return EBADMEM; 763 } 764 if(! addrlen){ 765 return NO_DATA; 766 } 731 767 // with the address 732 return recvfrom_core( NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen ); 733 } 734 735 int recvfrom_core( ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen ){ 736 socket_ref socket; 737 aid_t message_id; 738 ipcarg_t ipc_result; 739 int result; 740 size_t fragments; 741 size_t * lengths; 742 size_t index; 743 ipc_call_t answer; 744 745 if( ! data ) return EBADMEM; 746 if( ! datalength ) return NO_DATA; 747 if( fromaddr && ( ! addrlen )) return EINVAL; 748 fibril_rwlock_read_lock( & socket_globals.lock ); 768 return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen); 769 } 770 771 int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){ 772 socket_ref socket; 773 aid_t message_id; 774 ipcarg_t ipc_result; 775 int result; 776 size_t fragments; 777 size_t * lengths; 778 size_t index; 779 ipc_call_t answer; 780 781 if(! data){ 782 return EBADMEM; 783 } 784 if(! datalength){ 785 return NO_DATA; 786 } 787 if(fromaddr && (! addrlen)){ 788 return EINVAL; 789 } 790 fibril_rwlock_read_lock(&socket_globals.lock); 749 791 // find the socket 750 socket = sockets_find( socket_get_sockets(), socket_id);751 if( ! socket){752 fibril_rwlock_read_unlock( & socket_globals.lock);792 socket = sockets_find(socket_get_sockets(), socket_id); 793 if(! socket){ 794 fibril_rwlock_read_unlock(&socket_globals.lock); 753 795 return ENOTSOCK; 754 796 } 755 fibril_mutex_lock( & socket->receive_lock);797 fibril_mutex_lock(&socket->receive_lock); 756 798 // wait for a received packet 757 799 ++ socket->blocked; 758 while(( result = dyn_fifo_value( & socket->received )) <= 0){759 fibril_rwlock_read_unlock( & socket_globals.lock);760 fibril_condvar_wait( & socket->receive_signal, & socket->receive_lock);761 fibril_rwlock_read_lock( & socket_globals.lock);800 while((result = dyn_fifo_value(&socket->received)) <= 0){ 801 fibril_rwlock_read_unlock(&socket_globals.lock); 802 fibril_condvar_wait(&socket->receive_signal, &socket->receive_lock); 803 fibril_rwlock_read_lock(&socket_globals.lock); 762 804 } 763 805 -- socket->blocked; 764 fragments = ( size_t) result;806 fragments = (size_t) result; 765 807 // prepare lengths if more fragments 766 if( fragments > 1){767 lengths = ( size_t * ) malloc( sizeof( size_t ) * fragments + sizeof( size_t));768 if( ! lengths){769 fibril_mutex_unlock( & socket->receive_lock);770 fibril_rwlock_read_unlock( & socket_globals.lock);808 if(fragments > 1){ 809 lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t)); 810 if(! lengths){ 811 fibril_mutex_unlock(&socket->receive_lock); 812 fibril_rwlock_read_unlock(&socket_globals.lock); 771 813 return ENOMEM; 772 814 } 773 815 // request packet data 774 message_id = async_send_4( socket->phone, message, ( ipcarg_t ) socket->socket_id, 0, socket->service, ( ipcarg_t ) flags, & answer);816 message_id = async_send_4(socket->phone, message, (ipcarg_t) socket->socket_id, 0, socket->service, (ipcarg_t) flags, &answer); 775 817 // read the address if desired 776 if(( ! fromaddr ) || ( async_data_read_start( socket->phone, fromaddr, * addrlen ) == EOK)){818 if((! fromaddr) || (async_data_read_start(socket->phone, fromaddr, * addrlen) == EOK)){ 777 819 // read the fragment lengths 778 if( async_data_read_start( socket->phone, lengths, sizeof( int ) * ( fragments + 1 )) == EOK){779 if( lengths[ fragments ] <= datalength){820 if(async_data_read_start(socket->phone, lengths, sizeof(int) * (fragments + 1)) == EOK){ 821 if(lengths[fragments] <= datalength){ 780 822 // read all fragments if long enough 781 for( index = 0; index < fragments; ++ index){782 async_data_read_start( socket->phone, data, lengths[ index ]);783 data = (( uint8_t * ) data ) + lengths[ index];823 for(index = 0; index < fragments; ++ index){ 824 async_data_read_start(socket->phone, data, lengths[index]); 825 data = ((uint8_t *) data) + lengths[index]; 784 826 } 785 827 } 786 828 } 787 829 } 788 free( lengths);830 free(lengths); 789 831 }else{ 790 832 // request packet data 791 message_id = async_send_4( socket->phone, message, ( ipcarg_t ) socket->socket_id, 0, socket->service, ( ipcarg_t ) flags, & answer);833 message_id = async_send_4(socket->phone, message, (ipcarg_t) socket->socket_id, 0, socket->service, (ipcarg_t) flags, &answer); 792 834 // read the address if desired 793 if(( ! fromaddr ) || ( async_data_read_start( socket->phone, fromaddr, * addrlen ) == EOK)){835 if((! fromaddr) || (async_data_read_start(socket->phone, fromaddr, * addrlen) == EOK)){ 794 836 // read all if only one fragment 795 async_data_read_start( socket->phone, data, datalength);796 } 797 } 798 async_wait_for( message_id, & ipc_result);837 async_data_read_start(socket->phone, data, datalength); 838 } 839 } 840 async_wait_for(message_id, &ipc_result); 799 841 result = (int) ipc_result; 800 842 // if successful 801 if( result == EOK){843 if(result == EOK){ 802 844 // dequeue the received packet 803 dyn_fifo_pop( & socket->received);845 dyn_fifo_pop(&socket->received); 804 846 // return read data length 805 result = SOCKET_GET_READ_DATA_LENGTH( answer);847 result = SOCKET_GET_READ_DATA_LENGTH(answer); 806 848 // set address length 807 if( fromaddr && addrlen ) * addrlen = SOCKET_GET_ADDRESS_LENGTH( answer ); 808 } 809 fibril_mutex_unlock( & socket->receive_lock ); 810 fibril_rwlock_read_unlock( & socket_globals.lock ); 849 if(fromaddr && addrlen){ 850 *addrlen = SOCKET_GET_ADDRESS_LENGTH(answer); 851 } 852 } 853 fibril_mutex_unlock(&socket->receive_lock); 854 fibril_rwlock_read_unlock(&socket_globals.lock); 811 855 return result; 812 856 } 813 857 814 int getsockopt( int socket_id, int level, int optname, void * value, size_t * optlen ){ 815 socket_ref socket; 816 aid_t message_id; 817 ipcarg_t result; 818 819 if( !( value && optlen )) return EBADMEM; 820 if( !( * optlen )) return NO_DATA; 821 fibril_rwlock_read_lock( & socket_globals.lock ); 858 int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen){ 859 socket_ref socket; 860 aid_t message_id; 861 ipcarg_t result; 862 863 if(!(value && optlen)){ 864 return EBADMEM; 865 } 866 if(!(*optlen)){ 867 return NO_DATA; 868 } 869 fibril_rwlock_read_lock(&socket_globals.lock); 822 870 // find the socket 823 socket = sockets_find( socket_get_sockets(), socket_id);824 if( ! socket){825 fibril_rwlock_read_unlock( & socket_globals.lock);871 socket = sockets_find(socket_get_sockets(), socket_id); 872 if(! socket){ 873 fibril_rwlock_read_unlock(&socket_globals.lock); 826 874 return ENOTSOCK; 827 875 } 828 876 // request option value 829 message_id = async_send_3( socket->phone, NET_SOCKET_GETSOCKOPT, ( ipcarg_t ) socket->socket_id, ( ipcarg_t ) optname, socket->service, NULL);877 message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, (ipcarg_t) socket->socket_id, (ipcarg_t) optname, socket->service, NULL); 830 878 // read the length 831 if( async_data_read_start( socket->phone, optlen, sizeof( * optlen )) == EOK){879 if(async_data_read_start(socket->phone, optlen, sizeof(*optlen)) == EOK){ 832 880 // read the value 833 async_data_read_start( socket->phone, value, * optlen);834 } 835 fibril_rwlock_read_unlock( & socket_globals.lock);836 async_wait_for( message_id, & result);837 return ( int) result;838 } 839 840 int setsockopt( int socket_id, int level, int optname, const void * value, size_t optlen){881 async_data_read_start(socket->phone, value, * optlen); 882 } 883 fibril_rwlock_read_unlock(&socket_globals.lock); 884 async_wait_for(message_id, &result); 885 return (int) result; 886 } 887 888 int setsockopt(int socket_id, int level, int optname, const void * value, size_t optlen){ 841 889 // send the value 842 return socket_send_data( socket_id, NET_SOCKET_SETSOCKOPT, ( ipcarg_t ) optname, value, optlen);890 return socket_send_data(socket_id, NET_SOCKET_SETSOCKOPT, (ipcarg_t) optname, value, optlen); 843 891 844 892 } -
uspace/srv/net/socket/socket_core.c
raa85487 raadf01e 64 64 /** The bound sockets map. 65 65 */ 66 socket_port_map_t 66 socket_port_map_t map; 67 67 /** The bound sockets count. 68 68 */ 69 int 69 int count; 70 70 }; 71 71 … … 79 79 * @returns Other error codes as defined for the socket_ports_add() function. 80 80 */ 81 int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port);81 int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port); 82 82 83 83 /** Destroys the socket. … … 90 90 * @param[in] socket_release The client release callback function. 91 91 */ 92 void socket_destroy_core( int packet_phone, socket_core_ref socket, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket));92 void socket_destroy_core(int packet_phone, socket_core_ref socket, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)); 93 93 94 94 /** Adds the socket to a socket port. … … 100 100 * @returns ENOMEM if there is not enough memory left. 101 101 */ 102 int socket_port_add_core( socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length);102 int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length); 103 103 104 104 /** Tries to find a new free socket identifier. … … 108 108 * @returns ELIMIT if there is no socket identifier available. 109 109 */ 110 static int socket_generate_new_id( socket_cores_ref local_sockets, int positive);111 112 INT_MAP_IMPLEMENT( socket_cores, socket_core_t);113 114 GENERIC_CHAR_MAP_IMPLEMENT( socket_port_map, socket_core_ref);115 116 INT_MAP_IMPLEMENT( socket_ports, socket_port_t);117 118 void socket_cores_release( int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket)){119 if( socket_cores_is_valid( local_sockets)){120 int 110 static int socket_generate_new_id(socket_cores_ref local_sockets, int positive); 111 112 INT_MAP_IMPLEMENT(socket_cores, socket_core_t); 113 114 GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ref); 115 116 INT_MAP_IMPLEMENT(socket_ports, socket_port_t); 117 118 void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){ 119 if(socket_cores_is_valid(local_sockets)){ 120 int index; 121 121 122 122 local_sockets->magic = 0; 123 for( index = 0; index < local_sockets->next; ++ index){124 if( socket_cores_item_is_valid( &( local_sockets->items[ index ]))){125 local_sockets->items[ index].magic = 0;126 if( local_sockets->items[ index ].value){127 socket_destroy_core( packet_phone, local_sockets->items[ index ].value, local_sockets, global_sockets, socket_release);128 free( local_sockets->items[ index ].value);129 local_sockets->items[ index].value = NULL;123 for(index = 0; index < local_sockets->next; ++ index){ 124 if(socket_cores_item_is_valid(&(local_sockets->items[index]))){ 125 local_sockets->items[index].magic = 0; 126 if(local_sockets->items[index].value){ 127 socket_destroy_core(packet_phone, local_sockets->items[index].value, local_sockets, global_sockets, socket_release); 128 free(local_sockets->items[index].value); 129 local_sockets->items[index].value = NULL; 130 130 } 131 131 } 132 132 } 133 free( local_sockets->items);134 } 135 } 136 137 void socket_destroy_core( int packet_phone, socket_core_ref socket, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket)){138 int 133 free(local_sockets->items); 134 } 135 } 136 137 void socket_destroy_core(int packet_phone, socket_core_ref socket, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){ 138 int packet_id; 139 139 140 140 // if bound 141 if( socket->port){141 if(socket->port){ 142 142 // release the port 143 socket_port_release( global_sockets, socket);143 socket_port_release(global_sockets, socket); 144 144 } 145 145 // release all received packets 146 while(( packet_id = dyn_fifo_pop( & socket->received )) >= 0 ){ 147 pq_release( packet_phone, packet_id ); 148 } 149 dyn_fifo_destroy( & socket->received ); 150 dyn_fifo_destroy( & socket->accepted ); 151 if( socket_release ){ 152 socket_release( socket ); 153 } 154 socket_cores_exclude( local_sockets, socket->socket_id ); 155 } 156 157 int socket_bind( socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port ){ 158 socket_core_ref socket; 159 socket_port_ref socket_port; 160 struct sockaddr * address; 161 struct sockaddr_in * address_in; 162 163 if( addrlen < sizeof( struct sockaddr )) return EINVAL; 164 address = ( struct sockaddr * ) addr; 165 switch( address->sa_family ){ 146 while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){ 147 pq_release(packet_phone, packet_id); 148 } 149 dyn_fifo_destroy(&socket->received); 150 dyn_fifo_destroy(&socket->accepted); 151 if(socket_release){ 152 socket_release(socket); 153 } 154 socket_cores_exclude(local_sockets, socket->socket_id); 155 } 156 157 int socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port){ 158 socket_core_ref socket; 159 socket_port_ref socket_port; 160 struct sockaddr * address; 161 struct sockaddr_in * address_in; 162 163 if(addrlen < sizeof(struct sockaddr)){ 164 return EINVAL; 165 } 166 address = (struct sockaddr *) addr; 167 switch(address->sa_family){ 166 168 case AF_INET: 167 if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; 168 address_in = ( struct sockaddr_in * ) addr; 169 if(addrlen != sizeof(struct sockaddr_in)){ 170 return EINVAL; 171 } 172 address_in = (struct sockaddr_in *) addr; 169 173 // find the socket 170 socket = socket_cores_find( local_sockets, socket_id ); 171 if( ! socket ) return ENOTSOCK; 174 socket = socket_cores_find(local_sockets, socket_id); 175 if(! socket){ 176 return ENOTSOCK; 177 } 172 178 // bind a free port? 173 if( address_in->sin_port <= 0){174 return socket_bind_free_port( global_sockets, socket, free_ports_start, free_ports_end, last_used_port);179 if(address_in->sin_port <= 0){ 180 return socket_bind_free_port(global_sockets, socket, free_ports_start, free_ports_end, last_used_port); 175 181 } 176 182 // try to find the port 177 socket_port = socket_ports_find( global_sockets, ntohs( address_in->sin_port));178 if( socket_port){183 socket_port = socket_ports_find(global_sockets, ntohs(address_in->sin_port)); 184 if(socket_port){ 179 185 // already used 180 186 return EADDRINUSE; 181 187 } 182 188 // if bound 183 if( socket->port){189 if(socket->port){ 184 190 // release the port 185 socket_port_release( global_sockets, socket);191 socket_port_release(global_sockets, socket); 186 192 } 187 193 socket->port = -1; 188 return socket_bind_insert( global_sockets, socket, ntohs( address_in->sin_port));194 return socket_bind_insert(global_sockets, socket, ntohs(address_in->sin_port)); 189 195 break; 190 196 // TODO IPv6 … … 193 199 } 194 200 195 int socket_bind_free_port( socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port){196 int 201 int socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port){ 202 int index; 197 203 198 204 // from the last used one … … 201 207 ++ index; 202 208 // til the range end 203 if( index >= free_ports_end){209 if(index >= free_ports_end){ 204 210 // start from the range beginning 205 211 index = free_ports_start - 1; … … 207 213 ++ index; 208 214 // til the last used one 209 if( index >= last_used_port){215 if(index >= last_used_port){ 210 216 // none found 211 217 return ENOTCONN; 212 218 } 213 }while( socket_ports_find( global_sockets, index ) != NULL);219 }while(socket_ports_find(global_sockets, index) != NULL); 214 220 // found, break immediately 215 221 break; 216 222 } 217 }while( socket_ports_find( global_sockets, index ) != NULL);218 return socket_bind_insert( global_sockets, socket, index);219 } 220 221 int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port){223 }while(socket_ports_find(global_sockets, index) != NULL); 224 return socket_bind_insert(global_sockets, socket, index); 225 } 226 227 int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){ 222 228 ERROR_DECLARE; 223 229 224 socket_port_ref 230 socket_port_ref socket_port; 225 231 226 232 // create a wrapper 227 socket_port = malloc( sizeof( * socket_port )); 228 if( ! socket_port ) return ENOMEM; 233 socket_port = malloc(sizeof(*socket_port)); 234 if(! socket_port){ 235 return ENOMEM; 236 } 229 237 socket_port->count = 0; 230 if( ERROR_OCCURRED( socket_port_map_initialize( & socket_port->map))231 || ERROR_OCCURRED( socket_port_add_core( socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){232 socket_port_map_destroy( & socket_port->map);233 free( socket_port);238 if(ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map)) 239 || ERROR_OCCURRED(socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){ 240 socket_port_map_destroy(&socket_port->map); 241 free(socket_port); 234 242 return ERROR_CODE; 235 243 } 236 244 // register the incomming port 237 ERROR_CODE = socket_ports_add( global_sockets, port, socket_port);238 if( ERROR_CODE < 0){239 socket_port_map_destroy( & socket_port->map);240 free( socket_port);245 ERROR_CODE = socket_ports_add(global_sockets, port, socket_port); 246 if(ERROR_CODE < 0){ 247 socket_port_map_destroy(&socket_port->map); 248 free(socket_port); 241 249 return ERROR_CODE; 242 250 } … … 246 254 247 255 248 static int socket_generate_new_id( socket_cores_ref local_sockets, int positive){249 int 250 int 256 static int socket_generate_new_id(socket_cores_ref local_sockets, int positive){ 257 int socket_id; 258 int count; 251 259 252 260 count = 0; 253 261 // socket_id = socket_globals.last_id; 254 262 do{ 255 if( count < SOCKET_ID_TRIES){263 if(count < SOCKET_ID_TRIES){ 256 264 socket_id = rand() % INT_MAX; 257 265 ++ count; 258 }else if( count == SOCKET_ID_TRIES){266 }else if(count == SOCKET_ID_TRIES){ 259 267 socket_id = 1; 260 268 ++ count; 261 269 // only this branch for last_id 262 270 }else{ 263 if( socket_id < INT_MAX){271 if(socket_id < INT_MAX){ 264 272 ++ socket_id; 265 /* }else if( socket_globals.last_id){273 /* }else if(socket_globals.last_id){ 266 274 * socket_globals.last_id = 0; 267 275 * socket_id = 1; … … 270 278 } 271 279 } 272 }while( socket_cores_find( local_sockets, (( positive ? 1 : -1 ) * socket_id)));280 }while(socket_cores_find(local_sockets, ((positive ? 1 : -1) * socket_id))); 273 281 // last_id = socket_id 274 282 return socket_id; 275 283 } 276 284 277 int socket_create( socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id){285 int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id){ 278 286 ERROR_DECLARE; 279 287 280 socket_core_ref socket; 281 int res; 282 int positive; 283 284 if( ! socket_id ) return EINVAL; 288 socket_core_ref socket; 289 int res; 290 int positive; 291 292 if(! socket_id){ 293 return EINVAL; 294 } 285 295 // store the socket 286 if( * socket_id <= 0){287 positive = ( * socket_id == 0);288 * socket_id = socket_generate_new_id( local_sockets, positive);289 if( * socket_id <= 0){296 if(*socket_id <= 0){ 297 positive = (*socket_id == 0); 298 *socket_id = socket_generate_new_id(local_sockets, positive); 299 if(*socket_id <= 0){ 290 300 return * socket_id; 291 301 } 292 if( ! positive){293 * 294 } 295 }else if( socket_cores_find( local_sockets, * socket_id)){302 if(! positive){ 303 *socket_id *= -1; 304 } 305 }else if(socket_cores_find(local_sockets, * socket_id)){ 296 306 return EEXIST; 297 307 } 298 socket = ( socket_core_ref ) malloc( sizeof( * socket )); 299 if( ! socket ) return ENOMEM; 308 socket = (socket_core_ref) malloc(sizeof(*socket)); 309 if(! socket){ 310 return ENOMEM; 311 } 300 312 // initialize 301 313 socket->phone = app_phone; … … 304 316 socket->key_length = 0; 305 317 socket->specific_data = specific_data; 306 if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->received, SOCKET_INITIAL_RECEIVED_SIZE))){307 free( socket);318 if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE))){ 319 free(socket); 308 320 return ERROR_CODE; 309 321 } 310 if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE))){311 dyn_fifo_destroy( & socket->received);312 free( socket);322 if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE))){ 323 dyn_fifo_destroy(&socket->received); 324 free(socket); 313 325 return ERROR_CODE; 314 326 } 315 327 socket->socket_id = * socket_id; 316 res = socket_cores_add( local_sockets, socket->socket_id, socket);317 if( res < 0){318 dyn_fifo_destroy( & socket->received);319 dyn_fifo_destroy( & socket->accepted);320 free( socket);328 res = socket_cores_add(local_sockets, socket->socket_id, socket); 329 if(res < 0){ 330 dyn_fifo_destroy(&socket->received); 331 dyn_fifo_destroy(&socket->accepted); 332 free(socket); 321 333 return res; 322 334 } … … 324 336 } 325 337 326 int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket)){327 socket_core_ref 328 int 338 int socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){ 339 socket_core_ref socket; 340 int accepted_id; 329 341 330 342 // find the socket 331 socket = socket_cores_find( local_sockets, socket_id ); 332 if( ! socket ) return ENOTSOCK; 343 socket = socket_cores_find(local_sockets, socket_id); 344 if(! socket){ 345 return ENOTSOCK; 346 } 333 347 // destroy all accepted sockets 334 while(( accepted_id = dyn_fifo_pop( & socket->accepted )) >= 0){335 socket_destroy( packet_phone, accepted_id, local_sockets, global_sockets, socket_release);336 } 337 socket_destroy_core( packet_phone, socket, local_sockets, global_sockets, socket_release);338 return EOK; 339 } 340 341 int socket_reply_packets( packet_t packet, size_t * length){348 while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){ 349 socket_destroy(packet_phone, accepted_id, local_sockets, global_sockets, socket_release); 350 } 351 socket_destroy_core(packet_phone, socket, local_sockets, global_sockets, socket_release); 352 return EOK; 353 } 354 355 int socket_reply_packets(packet_t packet, size_t * length){ 342 356 ERROR_DECLARE; 343 357 344 packet_t next_packet; 345 size_t fragments; 346 size_t * lengths; 347 size_t index; 348 349 if( ! length ) return EBADMEM; 350 next_packet = pq_next( packet ); 351 if( ! next_packet ){ 358 packet_t next_packet; 359 size_t fragments; 360 size_t * lengths; 361 size_t index; 362 363 if(! length){ 364 return EBADMEM; 365 } 366 next_packet = pq_next(packet); 367 if(! next_packet){ 352 368 // write all if only one fragment 353 ERROR_PROPAGATE( data_reply( packet_get_data( packet ), packet_get_data_length( packet)));369 ERROR_PROPAGATE(data_reply(packet_get_data(packet), packet_get_data_length(packet))); 354 370 // store the total length 355 * length = packet_get_data_length( packet);371 *length = packet_get_data_length(packet); 356 372 }else{ 357 373 // count the packet fragments 358 374 fragments = 1; 359 next_packet = pq_next( packet);360 while(( next_packet = pq_next( next_packet))){375 next_packet = pq_next(packet); 376 while((next_packet = pq_next(next_packet))){ 361 377 ++ fragments; 362 378 } 363 379 // compute and store the fragment lengths 364 lengths = ( size_t * ) malloc( sizeof( size_t ) * fragments + sizeof( size_t )); 365 if( ! lengths ) return ENOMEM; 366 lengths[ 0 ] = packet_get_data_length( packet ); 367 lengths[ fragments ] = lengths[ 0 ]; 368 next_packet = pq_next( packet ); 369 for( index = 1; index < fragments; ++ index ){ 370 lengths[ index ] = packet_get_data_length( next_packet ); 371 lengths[ fragments ] += lengths[ index ]; 372 next_packet = pq_next( packet ); 373 }while( next_packet ); 380 lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t)); 381 if(! lengths){ 382 return ENOMEM; 383 } 384 lengths[0] = packet_get_data_length(packet); 385 lengths[fragments] = lengths[0]; 386 next_packet = pq_next(packet); 387 for(index = 1; index < fragments; ++ index){ 388 lengths[index] = packet_get_data_length(next_packet); 389 lengths[fragments] += lengths[index]; 390 next_packet = pq_next(packet); 391 }while(next_packet); 374 392 // write the fragment lengths 375 ERROR_PROPAGATE( data_reply( lengths, sizeof( int ) * ( fragments + 1)));393 ERROR_PROPAGATE(data_reply(lengths, sizeof(int) * (fragments + 1))); 376 394 next_packet = packet; 377 395 // write the fragments 378 for( index = 0; index < fragments; ++ index){379 ERROR_PROPAGATE( data_reply( packet_get_data( next_packet ), lengths[ index ]));380 next_packet = pq_next( next_packet);381 }while( next_packet);396 for(index = 0; index < fragments; ++ index){ 397 ERROR_PROPAGATE(data_reply(packet_get_data(next_packet), lengths[index])); 398 next_packet = pq_next(next_packet); 399 }while(next_packet); 382 400 // store the total length 383 * length = lengths[ fragments];384 free( lengths);385 } 386 return EOK; 387 } 388 389 socket_core_ref socket_port_find( socket_ports_ref global_sockets, int port, const char * key, size_t key_length){390 socket_port_ref 391 socket_core_ref * 392 393 socket_port = socket_ports_find( global_sockets, port);394 if( socket_port && ( socket_port->count > 0)){395 socket_ref = socket_port_map_find( & socket_port->map, key, key_length);396 if( socket_ref){401 *length = lengths[fragments]; 402 free(lengths); 403 } 404 return EOK; 405 } 406 407 socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length){ 408 socket_port_ref socket_port; 409 socket_core_ref * socket_ref; 410 411 socket_port = socket_ports_find(global_sockets, port); 412 if(socket_port && (socket_port->count > 0)){ 413 socket_ref = socket_port_map_find(&socket_port->map, key, key_length); 414 if(socket_ref){ 397 415 return * socket_ref; 398 416 } … … 401 419 } 402 420 403 void socket_port_release( socket_ports_ref global_sockets, socket_core_ref socket){404 socket_port_ref 405 socket_core_ref * 406 407 if( socket->port){421 void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket){ 422 socket_port_ref socket_port; 423 socket_core_ref * socket_ref; 424 425 if(socket->port){ 408 426 // find ports 409 socket_port = socket_ports_find( global_sockets, socket->port);410 if( socket_port){427 socket_port = socket_ports_find(global_sockets, socket->port); 428 if(socket_port){ 411 429 // find the socket 412 socket_ref = socket_port_map_find( & socket_port->map, socket->key, socket->key_length);413 if( socket_ref){430 socket_ref = socket_port_map_find(&socket_port->map, socket->key, socket->key_length); 431 if(socket_ref){ 414 432 -- socket_port->count; 415 433 // release if empty 416 if( socket_port->count <= 0){434 if(socket_port->count <= 0){ 417 435 // destroy the map 418 socket_port_map_destroy( & socket_port->map);436 socket_port_map_destroy(&socket_port->map); 419 437 // release the port 420 socket_ports_exclude( global_sockets, socket->port);438 socket_ports_exclude(global_sockets, socket->port); 421 439 }else{ 422 440 // remove 423 socket_port_map_exclude( & socket_port->map, socket->key, socket->key_length);441 socket_port_map_exclude(&socket_port->map, socket->key, socket->key_length); 424 442 } 425 443 } … … 431 449 } 432 450 433 int socket_port_add( socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length){451 int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length){ 434 452 ERROR_DECLARE; 435 453 436 socket_port_ref 454 socket_port_ref socket_port; 437 455 438 456 // find ports 439 socket_port = socket_ports_find( global_sockets, port ); 440 if( ! socket_port ) return ENOENT; 457 socket_port = socket_ports_find(global_sockets, port); 458 if(! socket_port){ 459 return ENOENT; 460 } 441 461 // add the socket 442 ERROR_PROPAGATE( socket_port_add_core( socket_port, socket, key, key_length));462 ERROR_PROPAGATE(socket_port_add_core(socket_port, socket, key, key_length)); 443 463 socket->port = port; 444 464 return EOK; 445 465 } 446 466 447 int socket_port_add_core( socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){467 int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){ 448 468 ERROR_DECLARE; 449 469 450 socket_core_ref * 470 socket_core_ref * socket_ref; 451 471 452 472 // create a wrapper 453 socket_ref = malloc( sizeof( * socket_ref )); 454 if( ! socket_ref ) return ENOMEM; 455 * socket_ref = socket; 473 socket_ref = malloc(sizeof(*socket_ref)); 474 if(! socket_ref){ 475 return ENOMEM; 476 } 477 *socket_ref = socket; 456 478 // add the wrapper 457 if( ERROR_OCCURRED( socket_port_map_add( & socket_port->map, key, key_length, socket_ref))){458 free( socket_ref);479 if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){ 480 free(socket_ref); 459 481 return ERROR_CODE; 460 482 } -
uspace/srv/net/socket/socket_core.h
raa85487 raadf01e 93 93 /** Socket identifier. 94 94 */ 95 int 95 int socket_id; 96 96 /** Client application phone. 97 97 */ 98 int 98 int phone; 99 99 /** Bound port. 100 100 */ 101 int 101 int port; 102 102 /** Received packets queue. 103 103 */ 104 dyn_fifo_t 104 dyn_fifo_t received; 105 105 /** Sockets for acceptance queue. 106 106 */ 107 dyn_fifo_t 107 dyn_fifo_t accepted; 108 108 /** Protocol specific data. 109 109 */ 110 void * 110 void * specific_data; 111 111 /** Socket ports map key. 112 112 */ 113 const char * 113 const char * key; 114 114 /** Length of the Socket ports map key. 115 115 */ 116 size_t 116 size_t key_length; 117 117 }; 118 118 … … 120 120 * The key is the socket identifier. 121 121 */ 122 INT_MAP_DECLARE( socket_cores, socket_core_t);122 INT_MAP_DECLARE(socket_cores, socket_core_t); 123 123 124 124 /** Bount port sockets map. 125 125 * The listening socket has the SOCKET_MAP_KEY_LISTENING key identifier whereas the other use the remote addresses. 126 126 */ 127 GENERIC_CHAR_MAP_DECLARE( socket_port_map, socket_core_ref);127 GENERIC_CHAR_MAP_DECLARE(socket_port_map, socket_core_ref); 128 128 129 129 /** Ports map. 130 130 * The key is the port number. 131 131 */ 132 INT_MAP_DECLARE( socket_ports, socket_port_t);132 INT_MAP_DECLARE(socket_ports, socket_port_t); 133 133 134 134 /** Destroys local sockets. … … 139 139 * @param[in] socket_release The client release callback function. 140 140 */ 141 void socket_cores_release( int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket));141 void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)); 142 142 143 143 /** Binds the socket to the port. … … 158 158 * @returns Other error codes as defined for the socket_bind_insert() function. 159 159 */ 160 int socket_bind( socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port);160 int socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port); 161 161 162 162 /** Binds the socket to a free port. … … 171 171 * @returns Other error codes as defined for the socket_bind_insert() function. 172 172 */ 173 int socket_bind_free_port( socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port);173 int socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port); 174 174 175 175 /** Creates a new socket. … … 182 182 * @returns ENOMEM if there is not enough memory left. 183 183 */ 184 int socket_create( socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id);184 int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id); 185 185 186 186 /** Destroys the socket. … … 195 195 * @returns ENOTSOCK if the socket is not found. 196 196 */ 197 int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket));197 int socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)); 198 198 199 199 /** Replies the packet or the packet queue data to the application via the socket. … … 206 206 * @returns Other error codes as defined for the data_reply() function. 207 207 */ 208 int socket_reply_packets( packet_t packet, size_t * length);208 int socket_reply_packets(packet_t packet, size_t * length); 209 209 210 210 /** Finds the bound port socket. … … 216 216 * @returns NULL if no socket was found. 217 217 */ 218 socket_core_ref socket_port_find( socket_ports_ref global_sockets, int port, const char * key, size_t key_length);218 socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length); 219 219 220 220 /** Releases the socket port. … … 224 224 * @param[in] socket The socket to be unbound. 225 225 */ 226 void socket_port_release( socket_ports_ref global_sockets, socket_core_ref socket);226 void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket); 227 227 228 228 /** Adds the socket to an already bound port. … … 236 236 * @returns Other error codes as defined for the socket_port_add_core() function. 237 237 */ 238 int socket_port_add( socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length);238 int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length); 239 239 240 240 #endif -
uspace/srv/net/socket/socket_messages.h
raa85487 raadf01e 115 115 * @param[out] answer The message answer structure. 116 116 */ 117 #define SOCKET_SET_SOCKET_ID( answer ) ( int * ) & IPC_GET_ARG1( answer)117 #define SOCKET_SET_SOCKET_ID(answer) (int *) &IPC_GET_ARG1(answer) 118 118 119 119 /** Returns the socket identifier message parameter. 120 120 * @param[in] call The message call structure. 121 121 */ 122 #define SOCKET_GET_SOCKET_ID( call ) ( int ) IPC_GET_ARG1( call)122 #define SOCKET_GET_SOCKET_ID(call) (int) IPC_GET_ARG1(call) 123 123 124 124 /** Sets the read data length in the message answer. 125 125 * @param[out] answer The message answer structure. 126 126 */ 127 #define SOCKET_SET_READ_DATA_LENGTH( answer ) ( int * ) & IPC_GET_ARG1( answer)127 #define SOCKET_SET_READ_DATA_LENGTH(answer) (int *) &IPC_GET_ARG1(answer) 128 128 129 129 /** Returns the read data length message parameter. 130 130 * @param[in] call The message call structure. 131 131 */ 132 #define SOCKET_GET_READ_DATA_LENGTH( call ) ( int ) IPC_GET_ARG1( call)132 #define SOCKET_GET_READ_DATA_LENGTH(call) (int) IPC_GET_ARG1(call) 133 133 134 134 /** Returns the backlog message parameter. 135 135 * @param[in] call The message call structure. 136 136 */ 137 #define SOCKET_GET_BACKLOG( call ) ( int ) IPC_GET_ARG2( call)137 #define SOCKET_GET_BACKLOG(call) (int) IPC_GET_ARG2(call) 138 138 139 139 /** Returns the option level message parameter. 140 140 * @param[in] call The message call structure. 141 141 */ 142 #define SOCKET_GET_OPT_LEVEL( call ) ( int ) IPC_GET_ARG2( call)142 #define SOCKET_GET_OPT_LEVEL(call) (int) IPC_GET_ARG2(call) 143 143 144 144 /** Returns the data fragment size message parameter. 145 145 * @param[in] call The message call structure. 146 146 */ 147 #define SOCKET_GET_DATA_FRAGMENT_SIZE( call ) ( size_t ) IPC_GET_ARG2( call)147 #define SOCKET_GET_DATA_FRAGMENT_SIZE(call) (size_t) IPC_GET_ARG2(call) 148 148 149 149 /** Sets the data fragment size in the message answer. 150 150 * @param[out] answer The message answer structure. 151 151 */ 152 #define SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) ( size_t * ) & IPC_GET_ARG2( answer)152 #define SOCKET_SET_DATA_FRAGMENT_SIZE(answer) (size_t *) &IPC_GET_ARG2(answer) 153 153 154 154 /** Sets the address length in the message answer. 155 155 * @param[out] answer The message answer structure. 156 156 */ 157 #define SOCKET_SET_ADDRESS_LENGTH( answer ) ( socklen_t * ) & IPC_GET_ARG3( answer)157 #define SOCKET_SET_ADDRESS_LENGTH(answer) (socklen_t *) &IPC_GET_ARG3(answer) 158 158 159 159 /** Returns the address length message parameter. 160 160 * @param[in] call The message call structure. 161 161 */ 162 #define SOCKET_GET_ADDRESS_LENGTH( call ) ( socklen_t ) IPC_GET_ARG3( call)162 #define SOCKET_GET_ADDRESS_LENGTH(call) (socklen_t) IPC_GET_ARG3(call) 163 163 164 164 /** Sets the header size in the message answer. 165 165 * @param[out] answer The message answer structure. 166 166 */ 167 #define SOCKET_SET_HEADER_SIZE( answer ) ( int * ) & IPC_GET_ARG3( answer)167 #define SOCKET_SET_HEADER_SIZE(answer) (int *) &IPC_GET_ARG3(answer) 168 168 169 169 /** Returns the header size message parameter. 170 170 * @param[in] call The message call structure. 171 171 */ 172 #define SOCKET_GET_HEADER_SIZE( call ) ( int ) IPC_GET_ARG3( call)172 #define SOCKET_GET_HEADER_SIZE(call) (int) IPC_GET_ARG3(call) 173 173 174 174 /** Returns the flags message parameter. 175 175 * @param[in] call The message call structure. 176 176 */ 177 #define SOCKET_GET_FLAGS( call ) ( int ) IPC_GET_ARG4( call)177 #define SOCKET_GET_FLAGS(call) (int) IPC_GET_ARG4(call) 178 178 179 179 /** Returns the option name message parameter. 180 180 * @param[in] call The message call structure. 181 181 */ 182 #define SOCKET_GET_OPT_NAME( call ) ( int ) IPC_GET_ARG4( call)182 #define SOCKET_GET_OPT_NAME(call) (int) IPC_GET_ARG4(call) 183 183 184 184 /** Returns the data fragments message parameter. 185 185 * @param[in] call The message call structure. 186 186 */ 187 #define SOCKET_GET_DATA_FRAGMENTS( call ) ( int ) IPC_GET_ARG5( call)187 #define SOCKET_GET_DATA_FRAGMENTS(call) (int) IPC_GET_ARG5(call) 188 188 189 189 /** Returns the new socket identifier message parameter. 190 190 * @param[in] call The message call structure. 191 191 */ 192 #define SOCKET_GET_NEW_SOCKET_ID( call ) ( int ) IPC_GET_ARG5( call)192 #define SOCKET_GET_NEW_SOCKET_ID(call) (int) IPC_GET_ARG5(call) 193 193 194 194 /*@}*/
Note:
See TracChangeset
for help on using the changeset viewer.