Changes in uspace/srv/net/socket/socket_core.c [ede63e4:aadf01e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/socket/socket_core.c
rede63e4 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 }
Note:
See TracChangeset
for help on using the changeset viewer.