Changeset 3aae4e8 in mainline for uspace/lib/socket/generic/socket_client.c
- Timestamp:
- 2010-04-04T22:07:05Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 23de644
- Parents:
- 9f10660f (diff), 73060801 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/socket/generic/socket_client.c
r9f10660f r3aae4e8 45 45 #include <ipc/services.h> 46 46 47 #include "../err.h" 48 #include "../modules.h" 49 50 #include "../include/in.h" 51 #include "../include/socket.h" 52 #include "../include/socket_errno.h" 53 54 #include "../structures/dynamic_fifo.h" 55 #include "../structures/int_map.h" 56 57 #include "socket_messages.h" 47 #include <net_err.h> 48 #include <net_modules.h> 49 #include <in.h> 50 #include <socket.h> 51 #include <socket_errno.h> 52 #include <adt/dynamic_fifo.h> 53 #include <adt/int_map.h> 54 #include <socket_messages.h> 58 55 59 56 /** Initial received packet queue size. … … 191 188 INT_MAP_IMPLEMENT(sockets, socket_t); 192 189 193 /** Returns the TCP module phone.194 * Connects to the TCP module if necessary.195 * @returns The TCP module phone.196 * @returns Other error codes as defined for the bind_service_timeout() function.197 */198 static int socket_get_tcp_phone(void);199 200 /** Returns the UDP module phone.201 * Connects to the UDP module if necessary.202 * @returns The UDP module phone.203 * @returns Other error codes as defined for the bind_service_timeout() function.204 */205 static int socket_get_udp_phone(void);206 207 190 /** Returns the active sockets. 208 191 * @returns The active sockets. 209 192 */ 210 static sockets_ref socket_get_sockets(void);211 212 /** Tries to find a new free socket identifier.213 * @returns The new socket identifier.214 * @returns ELIMIT if there is no socket identifier available.215 */216 static int socket_generate_new_id(void);217 218 /** Default thread for new connections.219 * @param[in] iid The initial message identifier.220 * @param[in] icall The initial message call structure.221 */222 void socket_connection(ipc_callid_t iid, ipc_call_t * icall);223 224 /** Sends message to the socket parent module with specified data.225 * @param[in] socket_id Socket identifier.226 * @param[in] message The action message.227 * @param[in] arg2 The second message parameter.228 * @param[in] data The data to be sent.229 * @param[in] datalength The data length.230 * @returns EOK on success.231 * @returns ENOTSOCK if the socket is not found.232 * @returns EBADMEM if the data parameter is NULL.233 * @returns NO_DATA if the datalength parameter is zero (0).234 * @returns Other error codes as defined for the spcific message.235 */236 int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength);237 238 /** Initializes a new socket specific data.239 * @param[in,out] socket The socket to be initialized.240 * @param[in] socket_id The new socket identifier.241 * @param[in] phone The parent module phone.242 * @param[in] service The parent module service.243 */244 void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service);245 246 /** Clears and destroys the socket.247 * @param[in] socket The socket to be destroyed.248 */249 void socket_destroy(socket_ref socket);250 251 /** Receives data via the socket.252 * @param[in] message The action message.253 * @param[in] socket_id Socket identifier.254 * @param[out] data The data buffer to be filled.255 * @param[in] datalength The data length.256 * @param[in] flags Various receive flags.257 * @param[out] fromaddr The source address. May be NULL for connected sockets.258 * @param[in,out] addrlen The address length. The maximum address length is read. The actual address length is set. Used only if fromaddr is not NULL.259 * @returns EOK on success.260 * @returns ENOTSOCK if the socket is not found.261 * @returns EBADMEM if the data parameter is NULL.262 * @returns NO_DATA if the datalength or addrlen parameter is zero (0).263 * @returns Other error codes as defined for the spcific message.264 */265 int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen);266 267 /** Sends data via the socket to the remote address.268 * Binds the socket to a free port if not already connected/bound.269 * @param[in] message The action message.270 * @param[in] socket_id Socket identifier.271 * @param[in] data The data to be sent.272 * @param[in] datalength The data length.273 * @param[in] flags Various send flags.274 * @param[in] toaddr The destination address. May be NULL for connected sockets.275 * @param[in] addrlen The address length. Used only if toaddr is not NULL.276 * @returns EOK on success.277 * @returns ENOTSOCK if the socket is not found.278 * @returns EBADMEM if the data or toaddr parameter is NULL.279 * @returns NO_DATA if the datalength or the addrlen parameter is zero (0).280 * @returns Other error codes as defined for the NET_SOCKET_SENDTO message.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);287 }288 return socket_globals.tcp_phone;289 }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);294 }295 return socket_globals.udp_phone;296 }297 298 193 static sockets_ref socket_get_sockets(void){ 299 194 if(! socket_globals.sockets){ … … 311 206 } 312 207 313 static int socket_generate_new_id(void){ 314 sockets_ref sockets; 315 int socket_id; 316 int count; 317 318 sockets = socket_get_sockets(); 319 count = 0; 320 // socket_id = socket_globals.last_id; 321 do{ 322 if(count < SOCKET_ID_TRIES){ 323 socket_id = rand() % INT_MAX; 324 ++ count; 325 }else if(count == SOCKET_ID_TRIES){ 326 socket_id = 1; 327 ++ count; 328 // only this branch for last_id 329 }else{ 330 if(socket_id < INT_MAX){ 331 ++ socket_id; 332 /* }else if(socket_globals.last_id){ 333 * socket_globals.last_id = 0; 334 * socket_id = 1; 335 */ }else{ 336 return ELIMIT; 337 } 338 } 339 }while(sockets_find(sockets, socket_id)); 340 // last_id = socket_id 341 return socket_id; 342 } 343 344 void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service){ 345 socket->socket_id = socket_id; 346 socket->phone = phone; 347 socket->service = service; 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){ 208 /** Default thread for new connections. 209 * @param[in] iid The initial message identifier. 210 * @param[in] icall The initial message call structure. 211 */ 212 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall){ 358 213 ERROR_DECLARE; 359 214 … … 414 269 } 415 270 271 /** Returns the TCP module phone. 272 * Connects to the TCP module if necessary. 273 * @returns The TCP module phone. 274 * @returns Other error codes as defined for the bind_service_timeout() function. 275 */ 276 static int socket_get_tcp_phone(void){ 277 if(socket_globals.tcp_phone < 0){ 278 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT); 279 } 280 return socket_globals.tcp_phone; 281 } 282 283 /** Returns the UDP module phone. 284 * Connects to the UDP module if necessary. 285 * @returns The UDP module phone. 286 * @returns Other error codes as defined for the bind_service_timeout() function. 287 */ 288 static int socket_get_udp_phone(void){ 289 if(socket_globals.udp_phone < 0){ 290 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT); 291 } 292 return socket_globals.udp_phone; 293 } 294 295 /** Tries to find a new free socket identifier. 296 * @returns The new socket identifier. 297 * @returns ELIMIT if there is no socket identifier available. 298 */ 299 static int socket_generate_new_id(void){ 300 sockets_ref sockets; 301 int socket_id; 302 int count; 303 304 sockets = socket_get_sockets(); 305 count = 0; 306 // socket_id = socket_globals.last_id; 307 do{ 308 if(count < SOCKET_ID_TRIES){ 309 socket_id = rand() % INT_MAX; 310 ++ count; 311 }else if(count == SOCKET_ID_TRIES){ 312 socket_id = 1; 313 ++ count; 314 // only this branch for last_id 315 }else{ 316 if(socket_id < INT_MAX){ 317 ++ socket_id; 318 /* }else if(socket_globals.last_id){ 319 * socket_globals.last_id = 0; 320 * socket_id = 1; 321 */ }else{ 322 return ELIMIT; 323 } 324 } 325 }while(sockets_find(sockets, socket_id)); 326 // last_id = socket_id 327 return socket_id; 328 } 329 330 /** Initializes a new socket specific data. 331 * @param[in,out] socket The socket to be initialized. 332 * @param[in] socket_id The new socket identifier. 333 * @param[in] phone The parent module phone. 334 * @param[in] service The parent module service. 335 */ 336 static void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service){ 337 socket->socket_id = socket_id; 338 socket->phone = phone; 339 socket->service = service; 340 dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE); 341 dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE); 342 fibril_mutex_initialize(&socket->receive_lock); 343 fibril_condvar_initialize(&socket->receive_signal); 344 fibril_mutex_initialize(&socket->accept_lock); 345 fibril_condvar_initialize(&socket->accept_signal); 346 fibril_rwlock_initialize(&socket->sending_lock); 347 } 348 416 349 int socket(int domain, int type, int protocol){ 417 350 ERROR_DECLARE; … … 503 436 } 504 437 505 int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength){ 438 /** Sends message to the socket parent module with specified data. 439 * @param[in] socket_id Socket identifier. 440 * @param[in] message The action message. 441 * @param[in] arg2 The second message parameter. 442 * @param[in] data The data to be sent. 443 * @param[in] datalength The data length. 444 * @returns EOK on success. 445 * @returns ENOTSOCK if the socket is not found. 446 * @returns EBADMEM if the data parameter is NULL. 447 * @returns NO_DATA if the datalength parameter is zero (0). 448 * @returns Other error codes as defined for the spcific message. 449 */ 450 static int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength){ 506 451 socket_ref socket; 507 452 aid_t message_id; … … 650 595 } 651 596 597 /** Clears and destroys the socket. 598 * @param[in] socket The socket to be destroyed. 599 */ 600 static void socket_destroy(socket_ref socket){ 601 int accepted_id; 602 603 // destroy all accepted sockets 604 while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){ 605 socket_destroy(sockets_find(socket_get_sockets(), accepted_id)); 606 } 607 dyn_fifo_destroy(&socket->received); 608 dyn_fifo_destroy(&socket->accepted); 609 sockets_exclude(socket_get_sockets(), socket->socket_id); 610 } 611 652 612 int closesocket(int socket_id){ 653 613 ERROR_DECLARE; … … 673 633 } 674 634 675 void socket_destroy(socket_ref socket){ 676 int accepted_id; 677 678 // destroy all accepted sockets 679 while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){ 680 socket_destroy(sockets_find(socket_get_sockets(), accepted_id)); 681 } 682 dyn_fifo_destroy(&socket->received); 683 dyn_fifo_destroy(&socket->accepted); 684 sockets_exclude(socket_get_sockets(), socket->socket_id); 685 } 686 687 int send(int socket_id, void * data, size_t datalength, int flags){ 688 // without the address 689 return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0); 690 } 691 692 int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){ 693 if(! toaddr){ 694 return EDESTADDRREQ; 695 } 696 if(! addrlen){ 697 return EDESTADDRREQ; 698 } 699 // with the address 700 return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen); 701 } 702 703 int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){ 635 /** Sends data via the socket to the remote address. 636 * Binds the socket to a free port if not already connected/bound. 637 * @param[in] message The action message. 638 * @param[in] socket_id Socket identifier. 639 * @param[in] data The data to be sent. 640 * @param[in] datalength The data length. 641 * @param[in] flags Various send flags. 642 * @param[in] toaddr The destination address. May be NULL for connected sockets. 643 * @param[in] addrlen The address length. Used only if toaddr is not NULL. 644 * @returns EOK on success. 645 * @returns ENOTSOCK if the socket is not found. 646 * @returns EBADMEM if the data or toaddr parameter is NULL. 647 * @returns NO_DATA if the datalength or the addrlen parameter is zero (0). 648 * @returns Other error codes as defined for the NET_SOCKET_SENDTO message. 649 */ 650 static int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){ 704 651 socket_ref socket; 705 652 aid_t message_id; … … 760 707 } 761 708 762 int recv(int socket_id, void * data, size_t datalength, int flags){709 int send(int socket_id, void * data, size_t datalength, int flags){ 763 710 // without the address 764 return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL);765 } 766 767 int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t *addrlen){768 if(! fromaddr){769 return E BADMEM;711 return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0); 712 } 713 714 int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){ 715 if(! toaddr){ 716 return EDESTADDRREQ; 770 717 } 771 718 if(! addrlen){ 772 return NO_DATA;719 return EDESTADDRREQ; 773 720 } 774 721 // with the address 775 return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen); 776 } 777 778 int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){ 722 return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen); 723 } 724 725 /** Receives data via the socket. 726 * @param[in] message The action message. 727 * @param[in] socket_id Socket identifier. 728 * @param[out] data The data buffer to be filled. 729 * @param[in] datalength The data length. 730 * @param[in] flags Various receive flags. 731 * @param[out] fromaddr The source address. May be NULL for connected sockets. 732 * @param[in,out] addrlen The address length. The maximum address length is read. The actual address length is set. Used only if fromaddr is not NULL. 733 * @returns EOK on success. 734 * @returns ENOTSOCK if the socket is not found. 735 * @returns EBADMEM if the data parameter is NULL. 736 * @returns NO_DATA if the datalength or addrlen parameter is zero (0). 737 * @returns Other error codes as defined for the spcific message. 738 */ 739 static int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){ 779 740 socket_ref socket; 780 741 aid_t message_id; … … 866 827 } 867 828 829 int recv(int socket_id, void * data, size_t datalength, int flags){ 830 // without the address 831 return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL); 832 } 833 834 int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){ 835 if(! fromaddr){ 836 return EBADMEM; 837 } 838 if(! addrlen){ 839 return NO_DATA; 840 } 841 // with the address 842 return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen); 843 } 844 868 845 int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen){ 869 846 socket_ref socket;
Note:
See TracChangeset
for help on using the changeset viewer.