Changeset 849ed54 in mainline for uspace/lib/socket
- Timestamp:
- 2010-03-30T18:39:04Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7553689
- Parents:
- 7d6fe4db
- Location:
- uspace/lib/socket
- Files:
-
- 45 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/socket/Makefile
r7d6fe4db r849ed54 28 28 # 29 29 30 NET_BASE = ../.. 31 USPACE_PREFIX = ../../../.. 32 LIBS = $(NET_BASE)/socket/libsocket.a 33 BINARY = ping 30 USPACE_PREFIX = ../.. 31 EXTRA_CFLAGS = -Iinclude 32 LIBRARY = libsocket 34 33 35 34 SOURCES = \ 36 ping.c \ 37 $(NET_BASE)/app/parse.c \ 38 $(NET_BASE)/app/print_error.c \ 39 $(NET_BASE)/inet.c \ 40 $(NET_BASE)/modules.c \ 41 $(NET_BASE)/tl/icmp/icmp_api.c \ 42 $(NET_BASE)/tl/icmp/icmp_common.c 35 generic/socket_client.c \ 36 generic/socket_core.c \ 37 generic/inet.c \ 38 generic/net_modules.c \ 39 generic/icmp_common.c \ 40 generic/icmp_api.c \ 41 packet/packet.c \ 42 packet/packet_client.c \ 43 packet/packet_server.c \ 44 adt/dynamic_fifo.c \ 45 adt/measured_strings.c \ 46 adt/char_map.c 43 47 44 48 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/socket/adt/char_map.c
r7d6fe4db r849ed54 41 41 #include <unistd.h> 42 42 43 #include "char_map.h"43 #include <adt/char_map.h> 44 44 45 45 /** Internal magic value for a consistency check. -
uspace/lib/socket/adt/dynamic_fifo.c
r7d6fe4db r849ed54 39 39 #include <mem.h> 40 40 41 #include "dynamic_fifo.h"41 #include <adt/dynamic_fifo.h> 42 42 43 43 /** Internal magic value for a consistency check. … … 57 57 * @returns FALSE otherwise. 58 58 */ 59 int dyn_fifo_is_valid(dyn_fifo_ref fifo); 60 61 int dyn_fifo_is_valid(dyn_fifo_ref fifo){ 59 static int dyn_fifo_is_valid(dyn_fifo_ref fifo){ 62 60 return fifo && (fifo->magic_value == DYN_FIFO_MAGIC_VALUE); 63 61 } -
uspace/lib/socket/adt/measured_strings.c
r7d6fe4db r849ed54 43 43 #include <ipc/ipc.h> 44 44 45 #include "../err.h" 46 #include "../modules.h" 47 48 #include "measured_strings.h" 49 50 /** Computes the lengths of the measured strings in the given array. 51 * @param[in] strings The measured strings array to be processed. 52 * @param[in] count The measured strings array size. 53 * @returns The computed sizes array. 54 * @returns NULL if there is not enough memory left. 55 */ 56 size_t * prepare_lengths(const measured_string_ref strings, size_t count); 45 #include <net_err.h> 46 #include <net_modules.h> 47 #include <adt/measured_strings.h> 57 48 58 49 measured_string_ref measured_string_create_bulk(const char * string, size_t length){ … … 157 148 } 158 149 150 /** Computes the lengths of the measured strings in the given array. 151 * @param[in] strings The measured strings array to be processed. 152 * @param[in] count The measured strings array size. 153 * @returns The computed sizes array. 154 * @returns NULL if there is not enough memory left. 155 */ 156 static size_t * prepare_lengths(const measured_string_ref strings, size_t count){ 157 size_t * lengths; 158 size_t index; 159 size_t length; 160 161 lengths = (size_t *) malloc(sizeof(size_t) * (count + 1)); 162 if(! lengths){ 163 return NULL; 164 } 165 length = 0; 166 for(index = 0; index < count; ++ index){ 167 lengths[index] = strings[index].length; 168 length += lengths[index] + 1; 169 } 170 lengths[count] = length; 171 return lengths; 172 } 173 159 174 int measured_strings_reply(const measured_string_ref strings, size_t count){ 160 175 ERROR_DECLARE; … … 265 280 } 266 281 267 size_t * prepare_lengths(const measured_string_ref strings, size_t count){268 size_t * lengths;269 size_t index;270 size_t length;271 272 lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));273 if(! lengths){274 return NULL;275 }276 length = 0;277 for(index = 0; index < count; ++ index){278 lengths[index] = strings[index].length;279 length += lengths[index] + 1;280 }281 lengths[count] = length;282 return lengths;283 }284 285 282 /** @} 286 283 */ -
uspace/lib/socket/generic/icmp_api.c
r7d6fe4db r849ed54 43 43 #include <sys/types.h> 44 44 45 #include "../../modules.h" 46 47 #include "../../include/icmp_api.h" 48 #include "../../include/inet.h" 49 #include "../../include/ip_codes.h" 50 #include "../../include/socket_codes.h" 51 52 #include "icmp_messages.h" 45 #include <net_modules.h> 46 #include <icmp_api.h> 47 #include <inet.h> 48 #include <ip_codes.h> 49 #include <socket_codes.h> 50 #include <icmp_messages.h> 53 51 54 52 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){ -
uspace/lib/socket/generic/icmp_common.c
r7d6fe4db r849ed54 39 39 #include <ipc/services.h> 40 40 41 #include "../../modules.h" 42 43 #include "../../include/icmp_common.h" 44 45 #include "icmp_messages.h" 41 #include <net_modules.h> 42 #include <icmp_common.h> 43 #include <icmp_messages.h> 46 44 47 45 int icmp_connect_module(services_t service, suseconds_t timeout){ -
uspace/lib/socket/generic/inet.c
r7d6fe4db r849ed54 40 40 #include <str.h> 41 41 42 #include "include/in.h"43 #include "include/in6.h"44 #include "include/inet.h"45 #include "include/socket_codes.h"42 #include <in.h> 43 #include <in6.h> 44 #include <inet.h> 45 #include <socket_codes.h> 46 46 47 47 int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length){ -
uspace/lib/socket/generic/net_modules.c
r7d6fe4db r849ed54 43 43 #include <sys/time.h> 44 44 45 #include "err.h"46 #include "modules.h"45 #include <net_err.h> 46 #include <net_modules.h> 47 47 48 48 /** The time between connect requests in microseconds. -
uspace/lib/socket/generic/socket_client.c
r7d6fe4db r849ed54 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; -
uspace/lib/socket/generic/socket_core.c
r7d6fe4db r849ed54 38 38 #include <stdlib.h> 39 39 40 #include "../err.h" 41 42 #include "../include/in.h" 43 #include "../include/inet.h" 44 45 #include "../include/socket_codes.h" 46 #include "../include/socket_errno.h" 47 48 #include "../structures/dynamic_fifo.h" 49 #include "../structures/int_map.h" 50 #include "../structures/packet/packet.h" 51 #include "../structures/packet/packet_client.h" 52 53 #include "../modules.h" 54 55 #include "socket_core.h" 40 #include <net_err.h> 41 #include <in.h> 42 #include <inet.h> 43 #include <socket_codes.h> 44 #include <socket_errno.h> 45 #include <adt/dynamic_fifo.h> 46 #include <adt/int_map.h> 47 #include <packet/packet.h> 48 #include <packet/packet_client.h> 49 #include <net_modules.h> 50 #include <socket_core.h> 56 51 57 52 /** Maximum number of random attempts to find a new socket identifier before switching to the sequence. … … 70 65 }; 71 66 72 /** Binds the socket to the port. 73 * The SOCKET_MAP_KEY_LISTENING key identifier is used. 74 * @param[in] global_sockets The global sockets to be updated. 75 * @param[in] socket The socket to be added. 76 * @param[in] port The port number to be bound to. 77 * @returns EOK on success. 78 * @returns ENOMEM if there is not enough memory left. 79 * @returns Other error codes as defined for the socket_ports_add() function. 80 */ 81 int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port); 67 INT_MAP_IMPLEMENT(socket_cores, socket_core_t); 68 69 GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ref); 70 71 INT_MAP_IMPLEMENT(socket_ports, socket_port_t); 82 72 83 73 /** Destroys the socket. … … 90 80 * @param[in] socket_release The client release callback function. 91 81 */ 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 94 /** Adds the socket to a socket port. 95 * @param[in,out] socket_port The socket port structure. 96 * @param[in] socket The socket to be added. 97 * @param[in] key The socket key identifier. 98 * @param[in] key_length The socket key length. 99 * @returns EOK on success. 100 * @returns ENOMEM if there is not enough memory left. 101 */ 102 int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length); 103 104 /** Tries to find a new free socket identifier. 105 * @param[in] local_sockets The local sockets to be searched. 106 * @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false. 107 * @returns The new socket identifier. 108 * @returns ELIMIT if there is no socket identifier available. 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); 82 static 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)){ 83 int packet_id; 84 85 // if bound 86 if(socket->port){ 87 // release the port 88 socket_port_release(global_sockets, socket); 89 } 90 // release all received packets 91 while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){ 92 pq_release(packet_phone, packet_id); 93 } 94 dyn_fifo_destroy(&socket->received); 95 dyn_fifo_destroy(&socket->accepted); 96 if(socket_release){ 97 socket_release(socket); 98 } 99 socket_cores_exclude(local_sockets, socket->socket_id); 100 } 117 101 118 102 void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){ … … 135 119 } 136 120 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 140 // if bound 141 if(socket->port){ 142 // release the port 143 socket_port_release(global_sockets, socket); 144 } 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); 121 /** Adds the socket to a socket port. 122 * @param[in,out] socket_port The socket port structure. 123 * @param[in] socket The socket to be added. 124 * @param[in] key The socket key identifier. 125 * @param[in] key_length The socket key length. 126 * @returns EOK on success. 127 * @returns ENOMEM if there is not enough memory left. 128 */ 129 static int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){ 130 ERROR_DECLARE; 131 132 socket_core_ref * socket_ref; 133 134 // create a wrapper 135 socket_ref = malloc(sizeof(*socket_ref)); 136 if(! socket_ref){ 137 return ENOMEM; 138 } 139 *socket_ref = socket; 140 // add the wrapper 141 if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){ 142 free(socket_ref); 143 return ERROR_CODE; 144 } 145 ++ socket_port->count; 146 socket->key = key; 147 socket->key_length = key_length; 148 return EOK; 149 } 150 151 /** Binds the socket to the port. 152 * The SOCKET_MAP_KEY_LISTENING key identifier is used. 153 * @param[in] global_sockets The global sockets to be updated. 154 * @param[in] socket The socket to be added. 155 * @param[in] port The port number to be bound to. 156 * @returns EOK on success. 157 * @returns ENOMEM if there is not enough memory left. 158 * @returns Other error codes as defined for the socket_ports_add() function. 159 */ 160 static int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){ 161 ERROR_DECLARE; 162 163 socket_port_ref socket_port; 164 165 // create a wrapper 166 socket_port = malloc(sizeof(*socket_port)); 167 if(! socket_port){ 168 return ENOMEM; 169 } 170 socket_port->count = 0; 171 if(ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map)) 172 || ERROR_OCCURRED(socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){ 173 socket_port_map_destroy(&socket_port->map); 174 free(socket_port); 175 return ERROR_CODE; 176 } 177 // register the incomming port 178 ERROR_CODE = socket_ports_add(global_sockets, port, socket_port); 179 if(ERROR_CODE < 0){ 180 socket_port_map_destroy(&socket_port->map); 181 free(socket_port); 182 return ERROR_CODE; 183 } 184 socket->port = port; 185 return EOK; 155 186 } 156 187 … … 225 256 } 226 257 227 int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){ 228 ERROR_DECLARE; 229 230 socket_port_ref socket_port; 231 232 // create a wrapper 233 socket_port = malloc(sizeof(*socket_port)); 234 if(! socket_port){ 235 return ENOMEM; 236 } 237 socket_port->count = 0; 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); 242 return ERROR_CODE; 243 } 244 // register the incomming 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); 249 return ERROR_CODE; 250 } 251 socket->port = port; 252 return EOK; 253 } 254 255 258 /** Tries to find a new free socket identifier. 259 * @param[in] local_sockets The local sockets to be searched. 260 * @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false. 261 * @returns The new socket identifier. 262 * @returns ELIMIT if there is no socket identifier available. 263 */ 256 264 static int socket_generate_new_id(socket_cores_ref local_sockets, int positive){ 257 265 int socket_id; … … 465 473 } 466 474 467 int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){468 ERROR_DECLARE;469 470 socket_core_ref * socket_ref;471 472 // create a wrapper473 socket_ref = malloc(sizeof(*socket_ref));474 if(! socket_ref){475 return ENOMEM;476 }477 *socket_ref = socket;478 // add the wrapper479 if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){480 free(socket_ref);481 return ERROR_CODE;482 }483 ++ socket_port->count;484 socket->key = key;485 socket->key_length = key_length;486 return EOK;487 }488 489 475 /** @} 490 476 */ -
uspace/lib/socket/include/adt/char_map.h
r7d6fe4db r849ed54 89 89 * @returns Other error codes as defined for the char_map_add_item() function. 90 90 */ 91 int char_map_add(char_map_ref map, const char * identifier, size_t length, const int value);91 extern int char_map_add(char_map_ref map, const char * identifier, size_t length, const int value); 92 92 93 93 /** Clears and destroys the map. 94 94 * @param[in,out] map The character string to integer map. 95 95 */ 96 void char_map_destroy(char_map_ref map);96 extern void char_map_destroy(char_map_ref map); 97 97 98 98 /** Excludes the value assigned to the key from the map. … … 104 104 * @returns CHAR_MAP_NULL if the key is not assigned a value. 105 105 */ 106 int char_map_exclude(char_map_ref map, const char * identifier, size_t length);106 extern int char_map_exclude(char_map_ref map, const char * identifier, size_t length); 107 107 108 108 /** Returns the value assigned to the key from the map. … … 113 113 * @returns CHAR_MAP_NULL if the key is not assigned a value. 114 114 */ 115 int char_map_find(const char_map_ref map, const char * identifier, size_t length);115 extern int char_map_find(const char_map_ref map, const char * identifier, size_t length); 116 116 117 117 /** Initializes the map. … … 121 121 * @returns ENOMEM if there is not enough memory left. 122 122 */ 123 int char_map_initialize(char_map_ref map);123 extern int char_map_initialize(char_map_ref map); 124 124 125 125 /** Adds or updates the value with the key to the map. … … 135 135 * @returns Other error codes as defined for the char_map_add_item() function. 136 136 */ 137 int char_map_update(char_map_ref map, const char * identifier, size_t length, const int value);137 extern int char_map_update(char_map_ref map, const char * identifier, size_t length, const int value); 138 138 139 139 #endif -
uspace/lib/socket/include/adt/dynamic_fifo.h
r7d6fe4db r849ed54 79 79 * @returns ENOMEM if there is not enough memory left. 80 80 */ 81 int dyn_fifo_initialize(dyn_fifo_ref fifo, int size);81 extern int dyn_fifo_initialize(dyn_fifo_ref fifo, int size); 82 82 83 83 /** Appends a new item to the queue end. … … 89 89 * @returns ENOMEM if there is not enough memory left. 90 90 */ 91 int dyn_fifo_push(dyn_fifo_ref fifo, int value, int max_size);91 extern int dyn_fifo_push(dyn_fifo_ref fifo, int value, int max_size); 92 92 93 93 /** Returns and excludes the first item in the queue. … … 97 97 * @returns ENOENT if the queue is empty. 98 98 */ 99 int dyn_fifo_pop(dyn_fifo_ref fifo);99 extern int dyn_fifo_pop(dyn_fifo_ref fifo); 100 100 101 101 /** Returns and keeps the first item in the queue. … … 105 105 * @returns ENOENT if the queue is empty. 106 106 */ 107 int dyn_fifo_value(dyn_fifo_ref fifo);107 extern int dyn_fifo_value(dyn_fifo_ref fifo); 108 108 109 109 /** Clears and destroys the queue. … … 112 112 * @returns EINVAL if the queue is not valid. 113 113 */ 114 int dyn_fifo_destroy(dyn_fifo_ref fifo);114 extern int dyn_fifo_destroy(dyn_fifo_ref fifo); 115 115 116 116 #endif -
uspace/lib/socket/include/adt/generic_char_map.h
r7d6fe4db r849ed54 41 41 #include <unistd.h> 42 42 43 #include "../err.h"43 #include <net_err.h> 44 44 45 #include "char_map.h"46 #include "generic_field.h"45 #include <adt/char_map.h> 46 #include <adt/generic_field.h> 47 47 48 48 /** Internal magic value for a map consistency check. -
uspace/lib/socket/include/adt/measured_strings.h
r7d6fe4db r849ed54 71 71 * @returns NULL if there is not enough memory left. 72 72 */ 73 measured_string_ref measured_string_create_bulk(const char * string, size_t length);73 extern measured_string_ref measured_string_create_bulk(const char * string, size_t length); 74 74 75 75 /** Copies the given measured string with separated header and data parts. … … 79 79 * @returns NULL if there is not enough memory left. 80 80 */ 81 measured_string_ref measured_string_copy(measured_string_ref source);81 extern measured_string_ref measured_string_copy(measured_string_ref source); 82 82 83 83 /** Receives a measured strings array from a calling module. … … 95 95 * @returns Other error codes as defined for the async_data_write_finalize() function. 96 96 */ 97 int measured_strings_receive(measured_string_ref * strings, char ** data, size_t count);97 extern int measured_strings_receive(measured_string_ref * strings, char ** data, size_t count); 98 98 99 99 /** Replies the given measured strings array to a calling module. … … 108 108 * @returns Other error codes as defined for the async_data_read_finalize() function. 109 109 */ 110 int measured_strings_reply(const measured_string_ref strings, size_t count);110 extern int measured_strings_reply(const measured_string_ref strings, size_t count); 111 111 112 112 /** Receives a measured strings array from another module. … … 124 124 * @returns Other error codes as defined for the async_data_read_start() function. 125 125 */ 126 int measured_strings_return(int phone, measured_string_ref * strings, char ** data, size_t count);126 extern int measured_strings_return(int phone, measured_string_ref * strings, char ** data, size_t count); 127 127 128 128 /** Sends the given measured strings array to another module. … … 136 136 * @returns Other error codes as defined for the async_data_write_start() function. 137 137 */ 138 int measured_strings_send(int phone, const measured_string_ref strings, size_t count);138 extern int measured_strings_send(int phone, const measured_string_ref strings, size_t count); 139 139 140 140 #endif -
uspace/lib/socket/include/icmp_api.h
r7d6fe4db r849ed54 40 40 #include <sys/types.h> 41 41 42 #include "device.h" 43 44 #include "../structures/measured_strings.h" 45 #include "../structures/packet/packet.h" 46 47 #include "inet.h" 48 #include "ip_codes.h" 49 #include "socket_codes.h" 50 51 #include "icmp_codes.h" 52 #include "icmp_common.h" 42 #include <net_device.h> 43 #include <adt/measured_strings.h> 44 #include <packet/packet.h> 45 #include <inet.h> 46 #include <ip_codes.h> 47 #include <socket_codes.h> 48 #include <icmp_codes.h> 49 #include <icmp_common.h> 53 50 54 51 /** Miliseconds type definition. … … 79 76 * @returns EPARTY if there was an internal error. 80 77 */ 81 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen);78 extern int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen); 82 79 83 80 /*@}*/ -
uspace/lib/socket/include/icmp_common.h
r7d6fe4db r849ed54 53 53 * @returns ETIMEOUT if the connection timeouted. 54 54 */ 55 int icmp_connect_module(services_t service, suseconds_t timeout);55 extern int icmp_connect_module(services_t service, suseconds_t timeout); 56 56 57 57 #endif -
uspace/lib/socket/include/icmp_messages.h
r7d6fe4db r849ed54 40 40 41 41 #include <ipc/ipc.h> 42 43 42 #include <sys/types.h> 44 43 45 #include "../../include/icmp_codes.h" 46 47 #include "../../messages.h" 44 #include <icmp_codes.h> 45 #include <net_messages.h> 48 46 49 47 /** ICMP module messages. -
uspace/lib/socket/include/in.h
r7d6fe4db r849ed54 40 40 #include <sys/types.h> 41 41 42 #include "ip_protocols.h"43 #include "inet.h"42 #include <ip_protocols.h> 43 #include <inet.h> 44 44 45 45 /** INET string address maximum length. -
uspace/lib/socket/include/in6.h
r7d6fe4db r849ed54 40 40 #include <sys/types.h> 41 41 42 #include "ip_protocols.h"43 #include "inet.h"42 #include <ip_protocols.h> 43 #include <inet.h> 44 44 45 45 /** INET6 string address maximum length. -
uspace/lib/socket/include/inet.h
r7d6fe4db r849ed54 40 40 #include <sys/types.h> 41 41 42 #include "byteorder.h"42 #include <net_byteorder.h> 43 43 44 44 /** Type definition of the socket address. … … 62 62 * @returns ENOTSUP if the address family is not supported. 63 63 */ 64 int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length);64 extern int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length); 65 65 66 66 /** Parses the character string into the address. … … 74 74 * @returns ENOTSUP if the address family is not supported. 75 75 */ 76 int inet_pton(uint16_t family, const char * address, uint8_t * data);76 extern int inet_pton(uint16_t family, const char * address, uint8_t * data); 77 77 78 78 /** Socket address. -
uspace/lib/socket/include/net_device.h
r7d6fe4db r849ed54 38 38 #define __NET_DEVICE_ID_TYPE_H__ 39 39 40 #include "../structures/int_map.h"40 #include <adt/int_map.h> 41 41 42 42 /** Device identifier to generic type map declaration. -
uspace/lib/socket/include/net_messages.h
r7d6fe4db r849ed54 43 43 #include <ipc/services.h> 44 44 45 #include "include/device.h" 46 47 #include "structures/measured_strings.h" 48 #include "structures/packet/packet.h" 45 #include <net_device.h> 46 #include <adt/measured_strings.h> 47 #include <packet/packet.h> 49 48 50 49 /** Returns a value indicating whether the value is in the interval. -
uspace/lib/socket/include/net_modules.h
r7d6fe4db r849ed54 70 70 * @param[in] answer_count The number of answer parameters. 71 71 */ 72 void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count);72 extern void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count); 73 73 74 74 /** Creates bidirectional connection with the needed module service and registers the message receiver. … … 81 81 * @returns Other error codes as defined for the ipc_connect_to_me() function. 82 82 */ 83 int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver);83 extern int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver); 84 84 85 85 /** Creates bidirectional connection with the needed module service and registers the message receiver. … … 94 94 * @returns Other error codes as defined for the ipc_connect_to_me() function. 95 95 */ 96 int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout);96 extern int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout); 97 97 98 98 /** Connects to the needed module. … … 100 100 * @returns The phone of the needed service. 101 101 */ 102 int connect_to_service(services_t need);102 extern int connect_to_service(services_t need); 103 103 104 104 /** Connects to the needed module. … … 108 108 * @returns ETIMEOUT if the connection timeouted. 109 109 */ 110 int connect_to_service_timeout(services_t need, suseconds_t timeout);110 extern int connect_to_service_timeout(services_t need, suseconds_t timeout); 111 111 112 112 /** Receives data from the other party. … … 120 120 * @returns Other error codes as defined for the async_data_write_finalize() function. 121 121 */ 122 int data_receive(void ** data, size_t * length);122 extern int data_receive(void ** data, size_t * length); 123 123 124 124 /** Replies the data to the other party. … … 130 130 * @returns Other error codes as defined for the async_data_read_finalize() function. 131 131 */ 132 int data_reply(void * data, size_t data_length);132 extern int data_reply(void * data, size_t data_length); 133 133 134 134 /** Refreshes answer structure and parameters count. … … 137 137 * @param[in,out] answer_count The number of answer parameters. 138 138 */ 139 void refresh_answer(ipc_call_t * answer, int * answer_count);139 extern void refresh_answer(ipc_call_t * answer, int * answer_count); 140 140 141 141 #endif -
uspace/lib/socket/include/packet/packet.h
r7d6fe4db r849ed54 89 89 * @returns NULL if the mapping does not exist. 90 90 */ 91 packet_t pm_find(packet_id_t packet_id);91 extern packet_t pm_find(packet_id_t packet_id); 92 92 93 93 /** Adds the packet mapping. … … 98 98 * @returns ENOMEM if there is not enough memory left. 99 99 */ 100 int pm_add(packet_t packet);100 extern int pm_add(packet_t packet); 101 101 102 102 /** Initializes the packet map. … … 104 104 * @returns ENOMEM if there is not enough memory left. 105 105 */ 106 int pm_init(void);106 extern int pm_init(void); 107 107 108 108 /** Releases the packet map. 109 109 */ 110 void pm_destroy(void);110 extern void pm_destroy(void); 111 111 112 112 /** Add packet to the sorted queue. … … 121 121 * @returns EINVAL if the packet is not valid. 122 122 */ 123 int pq_add(packet_t * first, packet_t packet, size_t order, size_t metric);123 extern int pq_add(packet_t * first, packet_t packet, size_t order, size_t metric); 124 124 125 125 /** Finds the packet with the given order. … … 130 130 * @returns NULL if the packet is not found. 131 131 */ 132 packet_t pq_find(packet_t first, size_t order);132 extern packet_t pq_find(packet_t first, size_t order); 133 133 134 134 /** Inserts packet after the given one. … … 138 138 * @returns EINVAL if etiher of the packets is invalid. 139 139 */ 140 int pq_insert_after(packet_t packet, packet_t new_packet);140 extern int pq_insert_after(packet_t packet, packet_t new_packet); 141 141 142 142 /** Detach the packet from the queue. … … 146 146 * @returns NULL if the packet is not valid. 147 147 */ 148 packet_t pq_detach(packet_t packet);148 extern packet_t pq_detach(packet_t packet); 149 149 150 150 /** Sets the packet order and metric attributes. … … 155 155 * @returns EINVAL if the packet is invalid.. 156 156 */ 157 int pq_set_order(packet_t packet, size_t order, size_t metric);157 extern int pq_set_order(packet_t packet, size_t order, size_t metric); 158 158 159 159 /** Sets the packet order and metric attributes. … … 164 164 * @returns EINVAL if the packet is invalid.. 165 165 */ 166 int pq_get_order(packet_t packet, size_t * order, size_t * metric);166 extern int pq_get_order(packet_t packet, size_t * order, size_t * metric); 167 167 168 168 /** Releases the whole queue. … … 171 171 * @param[in] packet_release The releasing function called for each of the packets after its detachment. 172 172 */ 173 void pq_destroy(packet_t first, void (*packet_release)(packet_t packet));173 extern void pq_destroy(packet_t first, void (*packet_release)(packet_t packet)); 174 174 175 175 /** Returns the next packet in the queue. … … 179 179 * @returns NULL if the packet is not valid. 180 180 */ 181 packet_t pq_next(packet_t packet);181 extern packet_t pq_next(packet_t packet); 182 182 183 183 /** Returns the previous packet in the queue. … … 187 187 * @returns NULL if the packet is not valid. 188 188 */ 189 packet_t pq_previous(packet_t packet);189 extern packet_t pq_previous(packet_t packet); 190 190 191 191 /*@}*/ -
uspace/lib/socket/include/packet/packet_client.h
r7d6fe4db r849ed54 88 88 * @returns NULL if there is not enough memory left. 89 89 */ 90 void * packet_prefix(packet_t packet, size_t length);90 extern void * packet_prefix(packet_t packet, size_t length); 91 91 92 92 /** Allocates the specified space right after the actual packet content and returns its pointer. … … 96 96 * @returns NULL if there is not enough memory left. 97 97 */ 98 void * packet_suffix(packet_t packet, size_t length);98 extern void * packet_suffix(packet_t packet, size_t length); 99 99 100 100 /** Trims the actual packet content by the specified prefix and suffix lengths. … … 106 106 * @returns ENOMEM if there is not enough memory left. 107 107 */ 108 int packet_trim(packet_t packet, size_t prefix, size_t suffix);108 extern int packet_trim(packet_t packet, size_t prefix, size_t suffix); 109 109 110 110 /** Copies the specified data to the beginning of the actual packet content. … … 117 117 * @returns ENOMEM if there is not enough memory left. 118 118 */ 119 int packet_copy_data(packet_t packet, const void * data, size_t length);119 extern int packet_copy_data(packet_t packet, const void * data, size_t length); 120 120 121 121 /** Returns the packet identifier. … … 124 124 * @returns Zero (0) if the packet is not valid. 125 125 */ 126 packet_id_t packet_get_id(const packet_t packet);126 extern packet_id_t packet_get_id(const packet_t packet); 127 127 128 128 /** Returns the packet content length. … … 131 131 * @returns Zero (0) if the packet is not valid. 132 132 */ 133 size_t packet_get_data_length(const packet_t packet);133 extern size_t packet_get_data_length(const packet_t packet); 134 134 135 135 /** Returns the pointer to the beginning of the packet content. … … 138 138 * @returns NULL if the packet is not valid. 139 139 */ 140 void * packet_get_data(const packet_t packet);140 extern void * packet_get_data(const packet_t packet); 141 141 142 142 /** Returns the stored packet addresses and their length. … … 148 148 * @returns EINVAL if the packet is not valid. 149 149 */ 150 int packet_get_addr(const packet_t packet, uint8_t ** src, uint8_t ** dest);150 extern int packet_get_addr(const packet_t packet, uint8_t ** src, uint8_t ** dest); 151 151 152 152 /** Sets the packet addresses. … … 159 159 * @returns ENOMEM if there is not enough memory left. 160 160 */ 161 int packet_set_addr(packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len);161 extern int packet_set_addr(packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len); 162 162 163 163 /** Translates the packet identifier to the packet reference. … … 172 172 * @returns Other error codes as defined for the packet_return() function. 173 173 */ 174 int packet_translate(int phone, packet_ref packet, packet_id_t packet_id);174 extern int packet_translate(int phone, packet_ref packet, packet_id_t packet_id); 175 175 176 176 /** Obtains the packet of the given dimensions. … … 184 184 * @returns NULL on error. 185 185 */ 186 packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix);186 extern packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix); 187 187 188 188 /** Obtains the packet of the given content size. … … 193 193 * @returns NULL on error. 194 194 */ 195 packet_t packet_get_1(int phone, size_t content);195 extern packet_t packet_get_1(int phone, size_t content); 196 196 197 197 /** Releases the packet queue. … … 202 202 * @param[in] packet_id The packet identifier. 203 203 */ 204 void pq_release(int phone, packet_id_t packet_id);204 extern void pq_release(int phone, packet_id_t packet_id); 205 205 206 206 /** Returns the packet copy. … … 212 212 * @returns NULL on error. 213 213 */ 214 packet_t packet_get_copy(int phone, packet_t packet);214 extern packet_t packet_get_copy(int phone, packet_t packet); 215 215 216 216 /*@}*/ -
uspace/lib/socket/include/packet/packet_header.h
r7d6fe4db r849ed54 38 38 #define __NET_PACKET_HEADER_H__ 39 39 40 #include "packet.h"40 #include <packet/packet.h> 41 41 42 42 /** Returns the actual packet data length. -
uspace/lib/socket/include/packet/packet_messages.h
r7d6fe4db r849ed54 40 40 #include <ipc/ipc.h> 41 41 42 #include "../../messages.h"42 #include <net_messages.h> 43 43 44 44 /** Packet server module messages. -
uspace/lib/socket/include/packet/packet_server.h
r7d6fe4db r849ed54 56 56 * @returns Other error codes as defined for the packet_release_wrapper() function. 57 57 */ 58 int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);58 extern int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 59 59 60 60 #endif -
uspace/lib/socket/include/socket.h
r7d6fe4db r849ed54 40 40 #define __NET_SOCKET_H__ 41 41 42 #include "byteorder.h" 43 #include "in.h" 44 #include "in6.h" 45 #include "inet.h" 46 47 #include "socket_codes.h" 48 #include "socket_errno.h" 42 #include <net_byteorder.h> 43 #include <in.h> 44 #include <in6.h> 45 #include <inet.h> 46 #include <socket_codes.h> 47 #include <socket_errno.h> 49 48 50 49 /** @name Socket application programming interface … … 65 64 * @returns Other error codes as defined for the bind_service_timeout() function. 66 65 */ 67 int socket(int domain, int type, int protocol);66 extern int socket(int domain, int type, int protocol); 68 67 69 68 /** Binds the socket to a port address. … … 77 76 * @returns Other error codes as defined for the NET_SOCKET_BIND message. 78 77 */ 79 int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen);78 extern int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen); 80 79 81 80 /** Sets the number of connections waiting to be accepted. … … 87 86 * @returns Other error codes as defined for the NET_SOCKET_LISTEN message. 88 87 */ 89 int listen(int socket_id, int backlog);88 extern int listen(int socket_id, int backlog); 90 89 91 90 /** Accepts waiting socket. … … 100 99 * @returns Other error codes as defined for the NET_SOCKET_ACCEPT message. 101 100 */ 102 int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen);101 extern int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen); 103 102 104 103 /** Connects socket to the remote server. … … 112 111 * @returns Other error codes as defined for the NET_SOCKET_CONNECT message. 113 112 */ 114 int connect(int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen);113 extern int connect(int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen); 115 114 116 115 /** Closes the socket. … … 121 120 * @returns Other error codes as defined for the NET_SOCKET_CLOSE message. 122 121 */ 123 int closesocket(int socket_id);122 extern int closesocket(int socket_id); 124 123 125 124 /** Sends data via the socket. … … 134 133 * @returns Other error codes as defined for the NET_SOCKET_SEND message. 135 134 */ 136 int send(int socket_id, void * data, size_t datalength, int flags);135 extern int send(int socket_id, void * data, size_t datalength, int flags); 137 136 138 137 /** Sends data via the socket to the remote address. … … 150 149 * @returns Other error codes as defined for the NET_SOCKET_SENDTO message. 151 150 */ 152 int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen);151 extern int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen); 153 152 154 153 /** Receives data via the socket. … … 163 162 * @returns Other error codes as defined for the NET_SOCKET_RECV message. 164 163 */ 165 int recv(int socket_id, void * data, size_t datalength, int flags);164 extern int recv(int socket_id, void * data, size_t datalength, int flags); 166 165 167 166 /** Receives data via the socket. … … 178 177 * @returns Other error codes as defined for the NET_SOCKET_RECVFROM message. 179 178 */ 180 int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen);179 extern int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen); 181 180 182 181 /** Gets socket option. … … 192 191 * @returns Other error codes as defined for the NET_SOCKET_GETSOCKOPT message. 193 192 */ 194 int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen);193 extern int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen); 195 194 196 195 /** Sets socket option. … … 206 205 * @returns Other error codes as defined for the NET_SOCKET_SETSOCKOPT message. 207 206 */ 208 int setsockopt(int socket_id, int level, int optname, const void * value, size_t optlen);207 extern int setsockopt(int socket_id, int level, int optname, const void * value, size_t optlen); 209 208 210 209 /*@}*/ -
uspace/lib/socket/include/socket_core.h
r7d6fe4db r849ed54 40 40 #include <sys/types.h> 41 41 42 #include "../include/in.h" 43 #include "../include/device.h" 44 45 #include "../structures/generic_char_map.h" 46 #include "../structures/dynamic_fifo.h" 47 #include "../structures/int_map.h" 48 #include "../structures/packet/packet.h" 42 #include <in.h> 43 #include <net_device.h> 44 #include <adt/generic_char_map.h> 45 #include <adt/dynamic_fifo.h> 46 #include <adt/int_map.h> 47 #include <packet/packet.h> 49 48 50 49 /** Initial size of the received packet queue. … … 139 138 * @param[in] socket_release The client release callback function. 140 139 */ 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));140 extern 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 141 143 142 /** Binds the socket to the port. … … 158 157 * @returns Other error codes as defined for the socket_bind_insert() function. 159 158 */ 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);159 extern 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 160 162 161 /** Binds the socket to a free port. … … 171 170 * @returns Other error codes as defined for the socket_bind_insert() function. 172 171 */ 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);172 extern 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 173 175 174 /** Creates a new socket. … … 182 181 * @returns ENOMEM if there is not enough memory left. 183 182 */ 184 int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id);183 extern int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id); 185 184 186 185 /** Destroys the socket. … … 195 194 * @returns ENOTSOCK if the socket is not found. 196 195 */ 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));196 extern 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 197 199 198 /** Replies the packet or the packet queue data to the application via the socket. … … 206 205 * @returns Other error codes as defined for the data_reply() function. 207 206 */ 208 int socket_reply_packets(packet_t packet, size_t * length);207 extern int socket_reply_packets(packet_t packet, size_t * length); 209 208 210 209 /** Finds the bound port socket. … … 216 215 * @returns NULL if no socket was found. 217 216 */ 218 socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length);217 extern socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length); 219 218 220 219 /** Releases the socket port. … … 224 223 * @param[in] socket The socket to be unbound. 225 224 */ 226 void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket);225 extern void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket); 227 226 228 227 /** Adds the socket to an already bound port. … … 236 235 * @returns Other error codes as defined for the socket_port_add_core() function. 237 236 */ 238 int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length);237 extern int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length); 239 238 240 239 #endif -
uspace/lib/socket/include/socket_messages.h
r7d6fe4db r849ed54 42 42 #include <ipc/ipc.h> 43 43 44 #include "../messages.h" 45 46 #include "../include/socket_codes.h" 44 #include <net_messages.h> 45 #include <socket_codes.h> 47 46 48 47 /** Socket client messages. -
uspace/lib/socket/packet/packet.c
r7d6fe4db r849ed54 40 40 #include <mem.h> 41 41 #include <fibril_synch.h> 42 //#include <stdio.h>43 42 #include <unistd.h> 44 43 45 44 #include <sys/mman.h> 46 45 47 #include "../../err.h" 48 49 #include "../generic_field.h" 50 51 #include "packet.h" 52 #include "packet_header.h" 46 #include <net_err.h> 47 #include <adt/generic_field.h> 48 #include <packet/packet.h> 49 #include <packet/packet_header.h> 53 50 54 51 /** Packet map page size. -
uspace/lib/socket/packet/packet_client.c
r7d6fe4db r849ed54 38 38 #include <mem.h> 39 39 #include <unistd.h> 40 //#include <stdio.h>41 40 42 41 #include <sys/mman.h> 43 42 44 #include "../../messages.h" 45 46 #include "packet.h" 47 #include "packet_header.h" 48 #include "packet_client.h" 43 #include <net_messages.h> 44 #include <packet/packet.h> 45 #include <packet/packet_header.h> 46 #include <packet/packet_client.h> 49 47 50 48 int packet_copy_data(packet_t packet, const void * data, size_t length){ -
uspace/lib/socket/packet/packet_server.c
r7d6fe4db r849ed54 45 45 #include <sys/mman.h> 46 46 47 #include "../../err.h" 48 #include "../../messages.h" 49 50 #include "packet.h" 51 #include "packet_client.h" 52 #include "packet_header.h" 53 #include "packet_messages.h" 54 #include "packet_server.h" 47 #include <net_err.h> 48 #include <net_messages.h> 49 #include <packet/packet.h> 50 #include <packet/packet_client.h> 51 #include <packet/packet_header.h> 52 #include <packet/packet_messages.h> 53 #include <packet/packet_server.h> 55 54 56 55 #define FREE_QUEUES_COUNT 7 … … 98 97 }; 99 98 100 /** @name Packet server support functions 101 */ 102 /*@{*/ 103 104 /** Returns the packet of dimensions at least as given. 105 * Tries to reuse free packets first. 106 * Creates a new packet aligned to the memory page size if none available. 107 * Locks the global data during its processing. 108 * @param[in] addr_len The source and destination addresses maximal length in bytes. 109 * @param[in] max_prefix The maximal prefix length in bytes. 110 * @param[in] max_content The maximal content length in bytes. 111 * @param[in] max_suffix The maximal suffix length in bytes. 112 * @returns The packet of dimensions at least as given. 113 * @returns NULL if there is not enough memory left. 114 */ 115 packet_t packet_get(size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix); 116 117 /** Releases the packet queue. 118 * @param[in] packet_id The first packet identifier. 119 * @returns EOK on success. 120 * @returns ENOENT if there is no such packet. 121 */ 122 int packet_release_wrapper(packet_id_t packet_id); 123 124 /** Releases the packet and returns it to the appropriate free packet queue. 125 * Should be used only when the global data are locked. 126 * @param[in] packet The packet to be released. 127 */ 128 void packet_release(packet_t packet); 129 130 /** Creates a new packet of dimensions at least as given. 131 * Should be used only when the global data are locked. 132 * @param[in] length The total length of the packet, including the header, the addresses and the data of the packet. 133 * @param[in] addr_len The source and destination addresses maximal length in bytes. 134 * @param[in] max_prefix The maximal prefix length in bytes. 135 * @param[in] max_content The maximal content length in bytes. 136 * @param[in] max_suffix The maximal suffix length in bytes. 137 * @returns The packet of dimensions at least as given. 138 * @returns NULL if there is not enough memory left. 139 */ 140 packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix); 99 int packet_translate(int phone, packet_ref packet, packet_id_t packet_id){ 100 if(! packet){ 101 return EINVAL; 102 } 103 *packet = pm_find(packet_id); 104 return (*packet) ? EOK : ENOENT; 105 } 141 106 142 107 /** Clears and initializes the packet according to the given dimensions. … … 147 112 * @param[in] max_suffix The maximal suffix length in bytes. 148 113 */ 149 void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix); 150 151 /** Shares the packet memory block. 152 * @param[in] packet The packet to be shared. 153 * @returns EOK on success. 154 * @returns EINVAL if the packet is not valid. 155 * @returns EINVAL if the calling module does not accept the memory. 156 * @returns ENOMEM if the desired and actual sizes differ. 157 * @returns Other error codes as defined for the async_share_in_finalize() function. 158 */ 159 int packet_reply(const packet_t packet); 160 161 /*@}*/ 162 163 int packet_translate(int phone, packet_ref packet, packet_id_t packet_id){ 164 if(! packet){ 165 return EINVAL; 166 } 167 *packet = pm_find(packet_id); 168 return (*packet) ? EOK : ENOENT; 169 } 170 171 packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix){ 172 return packet_get(addr_len, max_prefix, max_content, max_suffix); 173 } 174 175 packet_t packet_get_1(int phone, size_t content){ 176 return packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content, DEFAULT_SUFFIX); 177 } 178 179 void pq_release(int phone, packet_id_t packet_id){ 180 (void) packet_release_wrapper(packet_id); 181 } 182 183 int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 184 packet_t packet; 185 186 *answer_count = 0; 187 switch(IPC_GET_METHOD(*call)){ 188 case IPC_M_PHONE_HUNGUP: 189 return EOK; 190 case NET_PACKET_CREATE_1: 191 packet = packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX); 192 if(! packet){ 193 return ENOMEM; 194 } 195 *answer_count = 2; 196 IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id); 197 IPC_SET_ARG2(*answer, (ipcarg_t) packet->length); 198 return EOK; 199 case NET_PACKET_CREATE_4: 200 packet = packet_get(((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(call)) ? IPC_GET_ADDR_LEN(call) : DEFAULT_ADDR_LEN), DEFAULT_PREFIX + IPC_GET_PREFIX(call), IPC_GET_CONTENT(call), DEFAULT_SUFFIX + IPC_GET_SUFFIX(call)); 201 if(! packet){ 202 return ENOMEM; 203 } 204 *answer_count = 2; 205 IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id); 206 IPC_SET_ARG2(*answer, (ipcarg_t) packet->length); 207 return EOK; 208 case NET_PACKET_GET: 209 packet = pm_find(IPC_GET_ID(call)); 210 if(! packet_is_valid(packet)){ 211 return ENOENT; 212 } 213 return packet_reply(packet); 214 case NET_PACKET_GET_SIZE: 215 packet = pm_find(IPC_GET_ID(call)); 216 if(! packet_is_valid(packet)){ 217 return ENOENT; 218 } 219 IPC_SET_ARG1(*answer, (ipcarg_t) packet->length); 220 *answer_count = 1; 221 return EOK; 222 case NET_PACKET_RELEASE: 223 return packet_release_wrapper(IPC_GET_ID(call)); 224 } 225 return ENOTSUP; 226 } 227 228 int packet_release_wrapper(packet_id_t packet_id){ 229 packet_t packet; 230 231 packet = pm_find(packet_id); 232 if(! packet_is_valid(packet)){ 233 return ENOENT; 234 } 235 fibril_mutex_lock(&ps_globals.lock); 236 pq_destroy(packet, packet_release); 237 fibril_mutex_unlock(&ps_globals.lock); 238 return EOK; 239 } 240 241 void packet_release(packet_t packet){ 242 int index; 243 int result; 244 245 // remove debug dump 246 // printf("packet %d released\n", packet->packet_id); 247 for(index = 0; (index < FREE_QUEUES_COUNT - 1) && (packet->length > ps_globals.sizes[index]); ++ index); 248 result = pq_add(&ps_globals.free[index], packet, packet->length, packet->length); 249 assert(result == EOK); 250 } 251 252 packet_t packet_get(size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){ 253 int index; 254 packet_t packet; 255 size_t length; 256 257 length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix + max_content + max_suffix, PAGE_SIZE); 258 fibril_mutex_lock(&ps_globals.lock); 259 for(index = 0; index < FREE_QUEUES_COUNT - 1; ++ index){ 260 if(length <= ps_globals.sizes[index]){ 261 packet = ps_globals.free[index]; 262 while(packet_is_valid(packet) && (packet->length < length)){ 263 packet = pm_find(packet->next); 264 } 265 if(packet_is_valid(packet)){ 266 if(packet == ps_globals.free[index]){ 267 ps_globals.free[index] = pq_detach(packet); 268 }else{ 269 pq_detach(packet); 270 } 271 packet_init(packet, addr_len, max_prefix, max_content, max_suffix); 272 fibril_mutex_unlock(&ps_globals.lock); 273 // remove debug dump 274 // printf("packet %d got\n", packet->packet_id); 275 return packet; 276 } 277 } 278 } 279 packet = packet_create(length, addr_len, max_prefix, max_content, max_suffix); 280 fibril_mutex_unlock(&ps_globals.lock); 281 // remove debug dump 282 // printf("packet %d created\n", packet->packet_id); 283 return packet; 284 } 285 286 packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){ 287 ERROR_DECLARE; 288 289 packet_t packet; 290 291 // already locked 292 packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0); 293 if(packet == MAP_FAILED){ 294 return NULL; 295 } 296 ++ ps_globals.count; 297 packet->packet_id = ps_globals.count; 298 packet->length = length; 299 packet_init(packet, addr_len, max_prefix, max_content, max_suffix); 300 packet->magic_value = PACKET_MAGIC_VALUE; 301 if(ERROR_OCCURRED(pm_add(packet))){ 302 munmap(packet, packet->length); 303 return NULL; 304 } 305 return packet; 306 } 307 308 void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){ 114 static void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){ 309 115 // clear the packet content 310 116 bzero(((void *) packet) + sizeof(struct packet), packet->length - sizeof(struct packet)); … … 323 129 } 324 130 325 int packet_reply(const packet_t packet){ 131 /** Creates a new packet of dimensions at least as given. 132 * Should be used only when the global data are locked. 133 * @param[in] length The total length of the packet, including the header, the addresses and the data of the packet. 134 * @param[in] addr_len The source and destination addresses maximal length in bytes. 135 * @param[in] max_prefix The maximal prefix length in bytes. 136 * @param[in] max_content The maximal content length in bytes. 137 * @param[in] max_suffix The maximal suffix length in bytes. 138 * @returns The packet of dimensions at least as given. 139 * @returns NULL if there is not enough memory left. 140 */ 141 static packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){ 142 ERROR_DECLARE; 143 144 packet_t packet; 145 146 // already locked 147 packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0); 148 if(packet == MAP_FAILED){ 149 return NULL; 150 } 151 ++ ps_globals.count; 152 packet->packet_id = ps_globals.count; 153 packet->length = length; 154 packet_init(packet, addr_len, max_prefix, max_content, max_suffix); 155 packet->magic_value = PACKET_MAGIC_VALUE; 156 if(ERROR_OCCURRED(pm_add(packet))){ 157 munmap(packet, packet->length); 158 return NULL; 159 } 160 return packet; 161 } 162 163 /** Returns the packet of dimensions at least as given. 164 * Tries to reuse free packets first. 165 * Creates a new packet aligned to the memory page size if none available. 166 * Locks the global data during its processing. 167 * @param[in] addr_len The source and destination addresses maximal length in bytes. 168 * @param[in] max_prefix The maximal prefix length in bytes. 169 * @param[in] max_content The maximal content length in bytes. 170 * @param[in] max_suffix The maximal suffix length in bytes. 171 * @returns The packet of dimensions at least as given. 172 * @returns NULL if there is not enough memory left. 173 */ 174 static packet_t packet_get(size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){ 175 int index; 176 packet_t packet; 177 size_t length; 178 179 length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix + max_content + max_suffix, PAGE_SIZE); 180 fibril_mutex_lock(&ps_globals.lock); 181 for(index = 0; index < FREE_QUEUES_COUNT - 1; ++ index){ 182 if(length <= ps_globals.sizes[index]){ 183 packet = ps_globals.free[index]; 184 while(packet_is_valid(packet) && (packet->length < length)){ 185 packet = pm_find(packet->next); 186 } 187 if(packet_is_valid(packet)){ 188 if(packet == ps_globals.free[index]){ 189 ps_globals.free[index] = pq_detach(packet); 190 }else{ 191 pq_detach(packet); 192 } 193 packet_init(packet, addr_len, max_prefix, max_content, max_suffix); 194 fibril_mutex_unlock(&ps_globals.lock); 195 // remove debug dump 196 // printf("packet %d got\n", packet->packet_id); 197 return packet; 198 } 199 } 200 } 201 packet = packet_create(length, addr_len, max_prefix, max_content, max_suffix); 202 fibril_mutex_unlock(&ps_globals.lock); 203 // remove debug dump 204 // printf("packet %d created\n", packet->packet_id); 205 return packet; 206 } 207 208 packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix){ 209 return packet_get(addr_len, max_prefix, max_content, max_suffix); 210 } 211 212 packet_t packet_get_1(int phone, size_t content){ 213 return packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content, DEFAULT_SUFFIX); 214 } 215 216 /** Releases the packet and returns it to the appropriate free packet queue. 217 * Should be used only when the global data are locked. 218 * @param[in] packet The packet to be released. 219 */ 220 static void packet_release(packet_t packet){ 221 int index; 222 int result; 223 224 // remove debug dump 225 // printf("packet %d released\n", packet->packet_id); 226 for(index = 0; (index < FREE_QUEUES_COUNT - 1) && (packet->length > ps_globals.sizes[index]); ++ index); 227 result = pq_add(&ps_globals.free[index], packet, packet->length, packet->length); 228 assert(result == EOK); 229 } 230 231 /** Releases the packet queue. 232 * @param[in] packet_id The first packet identifier. 233 * @returns EOK on success. 234 * @returns ENOENT if there is no such packet. 235 */ 236 static int packet_release_wrapper(packet_id_t packet_id){ 237 packet_t packet; 238 239 packet = pm_find(packet_id); 240 if(! packet_is_valid(packet)){ 241 return ENOENT; 242 } 243 fibril_mutex_lock(&ps_globals.lock); 244 pq_destroy(packet, packet_release); 245 fibril_mutex_unlock(&ps_globals.lock); 246 return EOK; 247 } 248 249 void pq_release(int phone, packet_id_t packet_id){ 250 (void) packet_release_wrapper(packet_id); 251 } 252 253 /** Shares the packet memory block. 254 * @param[in] packet The packet to be shared. 255 * @returns EOK on success. 256 * @returns EINVAL if the packet is not valid. 257 * @returns EINVAL if the calling module does not accept the memory. 258 * @returns ENOMEM if the desired and actual sizes differ. 259 * @returns Other error codes as defined for the async_share_in_finalize() function. 260 */ 261 static int packet_reply(const packet_t packet){ 326 262 ipc_callid_t callid; 327 263 size_t size; … … 337 273 } 338 274 275 int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 276 packet_t packet; 277 278 *answer_count = 0; 279 switch(IPC_GET_METHOD(*call)){ 280 case IPC_M_PHONE_HUNGUP: 281 return EOK; 282 case NET_PACKET_CREATE_1: 283 packet = packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX); 284 if(! packet){ 285 return ENOMEM; 286 } 287 *answer_count = 2; 288 IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id); 289 IPC_SET_ARG2(*answer, (ipcarg_t) packet->length); 290 return EOK; 291 case NET_PACKET_CREATE_4: 292 packet = packet_get(((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(call)) ? IPC_GET_ADDR_LEN(call) : DEFAULT_ADDR_LEN), DEFAULT_PREFIX + IPC_GET_PREFIX(call), IPC_GET_CONTENT(call), DEFAULT_SUFFIX + IPC_GET_SUFFIX(call)); 293 if(! packet){ 294 return ENOMEM; 295 } 296 *answer_count = 2; 297 IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id); 298 IPC_SET_ARG2(*answer, (ipcarg_t) packet->length); 299 return EOK; 300 case NET_PACKET_GET: 301 packet = pm_find(IPC_GET_ID(call)); 302 if(! packet_is_valid(packet)){ 303 return ENOENT; 304 } 305 return packet_reply(packet); 306 case NET_PACKET_GET_SIZE: 307 packet = pm_find(IPC_GET_ID(call)); 308 if(! packet_is_valid(packet)){ 309 return ENOENT; 310 } 311 IPC_SET_ARG1(*answer, (ipcarg_t) packet->length); 312 *answer_count = 1; 313 return EOK; 314 case NET_PACKET_RELEASE: 315 return packet_release_wrapper(IPC_GET_ID(call)); 316 } 317 return ENOTSUP; 318 } 319 339 320 /** @} 340 321 */
Note:
See TracChangeset
for help on using the changeset viewer.