Rev 4578 | Rev 4700 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4578 | Rev 4589 | ||
---|---|---|---|
Line 39... | Line 39... | ||
39 | #include "../include/inet.h" |
39 | #include "../include/inet.h" |
40 | 40 | ||
41 | #include "../include/socket.h" |
41 | #include "../include/socket.h" |
42 | #include "../include/socket_errno.h" |
42 | #include "../include/socket_errno.h" |
43 | 43 | ||
- | 44 | #include "../structures/dynamic_fifo.h" |
|
44 | #include "../structures/int_map.h" |
45 | #include "../structures/int_map.h" |
45 | #include "../structures/packet/packet.h" |
46 | #include "../structures/packet/packet.h" |
46 | #include "../structures/packet/packet_client.h" |
47 | #include "../structures/packet/packet_client.h" |
47 | 48 | ||
48 | #include "socket_core.h" |
49 | #include "socket_core.h" |
Line 63... | Line 64... | ||
63 | address = ( struct sockaddr * ) addr; |
64 | address = ( struct sockaddr * ) addr; |
64 | switch( address->sa_family ){ |
65 | switch( address->sa_family ){ |
65 | case AF_INET: |
66 | case AF_INET: |
66 | if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
67 | if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
67 | address_in = ( struct sockaddr_in * ) addr; |
68 | address_in = ( struct sockaddr_in * ) addr; |
- | 69 | // find the socket |
|
68 | socket = socket_cores_find( local_sockets, socket_id ); |
70 | socket = socket_cores_find( local_sockets, socket_id ); |
69 | if( ! socket ) return ENOTSOCK; |
71 | if( ! socket ) return ENOTSOCK; |
- | 72 | // try to find the port |
|
70 | socket_pointer = socket_ports_find( global_sockets, address_in->sin_port ); |
73 | socket_pointer = socket_ports_find( global_sockets, address_in->sin_port ); |
71 | if( * socket_pointer ){ |
74 | if( socket_pointer ){ |
- | 75 | // already used |
|
72 | return EADDRINUSE; |
76 | return EADDRINUSE; |
73 | } |
77 | } |
- | 78 | // disbind if bound |
|
74 | socket_ports_exclude( global_sockets, socket->port ); |
79 | socket_ports_exclude( global_sockets, socket->port ); |
- | 80 | // create a wrapper |
|
75 | socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer )); |
81 | socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer )); |
76 | if( ! socket_pointer ) return ENOMEM; |
82 | if( ! socket_pointer ) return ENOMEM; |
77 | * socket_pointer = socket; |
83 | * socket_pointer = socket; |
- | 84 | // register the port |
|
78 | ERROR_PROPAGATE( socket_ports_add( global_sockets, address_in->sin_port, socket_pointer )); |
85 | ERROR_CODE = socket_ports_add( global_sockets, address_in->sin_port, socket_pointer ); |
- | 86 | if( ERROR_CODE < 0 ){ |
|
- | 87 | free( socket_pointer ); |
|
- | 88 | } |
|
79 | socket->port = address_in->sin_port; |
89 | socket->port = address_in->sin_port; |
80 | break; |
90 | break; |
81 | // TODO IPv6 |
91 | // TODO IPv6 |
82 | default: |
92 | default: |
83 | return EAFNOSUPPORT; |
93 | return EAFNOSUPPORT; |
84 | } |
94 | } |
85 | return EOK; |
95 | return EOK; |
86 | } |
96 | } |
87 | 97 | ||
88 | int socket_create( socket_cores_ref local_sockets, int app_phone ){ |
98 | int socket_create( socket_cores_ref local_sockets, int app_phone, int * socket_id ){ |
- | 99 | ERROR_DECLARE; |
|
- | 100 | ||
89 | socket_core_ref socket; |
101 | socket_core_ref socket; |
90 | int res; |
102 | int res; |
91 | 103 | ||
- | 104 | if( ! socket_id ) return EBADMEM; |
|
92 | socket = ( socket_core_ref ) malloc( sizeof( * socket )); |
105 | socket = ( socket_core_ref ) malloc( sizeof( * socket )); |
93 | if( ! socket ) return ENOMEM; |
106 | if( ! socket ) return ENOMEM; |
- | 107 | // initialize |
|
94 | socket->phone = app_phone; |
108 | socket->phone = app_phone; |
95 | socket->port = -1; |
109 | socket->port = -1; |
96 | socket->device_id = -1; |
110 | socket->device_id = -1; |
97 | socket->peer_addr = NULL; |
111 | socket->peer_addr = NULL; |
98 | socket->connect_size = 2; |
- | |
99 | socket->receive_size = 8; |
- | |
100 | socket->connected = ( int * ) malloc( sizeof( int ) * socket->connect_size ); |
112 | if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->received, SOCKET_INITIAL_RECEIVED_SIZE ))){ |
101 | if( ! socket->connected ){ |
- | |
102 | free( socket ); |
113 | free( socket ); |
103 | return ENOMEM; |
114 | return ERROR_CODE; |
104 | } |
115 | } |
105 | bzero( socket->connected, sizeof( int ) * socket->connect_size ); |
- | |
106 | socket->received = ( int * ) malloc( sizeof( int ) * socket->receive_size ); |
116 | if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE ))){ |
107 | if( ! socket->received ){ |
117 | dyn_fifo_destroy( & socket->received ); |
108 | free( socket->connected ); |
- | |
109 | free( socket ); |
118 | free( socket ); |
110 | return ENOMEM; |
119 | return ERROR_CODE; |
111 | } |
120 | } |
112 | bzero( socket->received, sizeof( int ) * socket->receive_size ); |
121 | // get a next free socket number |
113 | socket->socket_id = socket_cores_count( local_sockets ) + 1; |
122 | socket->socket_id = socket_cores_count( local_sockets ) + 1; |
- | 123 | // store the socket |
|
114 | res = socket_cores_add( local_sockets, socket->socket_id, socket ); |
124 | res = socket_cores_add( local_sockets, socket->socket_id, socket ); |
115 | if( res < 0 ){ |
125 | if( res < 0 ){ |
116 | free( socket->received ); |
126 | dyn_fifo_destroy( & socket->received ); |
117 | free( socket->connected ); |
127 | dyn_fifo_destroy( & socket->accepted ); |
118 | free( socket ); |
128 | free( socket ); |
119 | return res; |
129 | return res; |
120 | } |
130 | } |
- | 131 | // return the socket identifier |
|
121 | return socket->socket_id; |
132 | * socket_id = socket->socket_id; |
- | 133 | return EOK; |
|
122 | } |
134 | } |
123 | 135 | ||
124 | int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets ){ |
136 | int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets ){ |
125 | socket_core_ref socket; |
137 | socket_core_ref socket; |
- | 138 | int accepted_id; |
|
126 | size_t i; |
139 | int packet_id; |
127 | 140 | ||
- | 141 | // find the socket |
|
128 | socket = socket_cores_find( local_sockets, socket_id ); |
142 | socket = socket_cores_find( local_sockets, socket_id ); |
129 | if( ! socket ) return ENOTSOCK; |
143 | if( ! socket ) return ENOTSOCK; |
130 | socket_ports_exclude( global_sockets, socket->port ); |
144 | socket_ports_exclude( global_sockets, socket->port ); |
131 | if( socket->connected ){ |
145 | // destroy all accepted sockets |
132 | for( i = 0; i < socket->connect_size; ++ i ){ |
146 | while(( accepted_id = dyn_fifo_pop( & socket->accepted ))){ |
133 | if( socket->connected[ i ] ){ |
- | |
134 | socket_destroy( packet_phone, socket->connected[ i ], local_sockets, global_sockets ); |
147 | socket_destroy( packet_phone, accepted_id, local_sockets, global_sockets ); |
135 | } |
- | |
136 | } |
- | |
137 | } |
148 | } |
138 | if( socket->received ){ |
149 | // release all received packets |
139 | for( i = 0; i < socket->receive_size; ++ i ){ |
150 | while(( packet_id = dyn_fifo_pop( & socket->received ))){ |
140 | if( socket->received[ i ] ){ |
- | |
141 | pq_release( packet_phone, socket->received[ i ] ); |
151 | pq_release( packet_phone, packet_id ); |
142 | } |
- | |
143 | } |
- | |
144 | } |
152 | } |
145 | if( socket->connected ) free( socket->connected ); |
153 | dyn_fifo_destroy( & socket->received ); |
146 | if( socket->received ) free( socket->received ); |
154 | dyn_fifo_destroy( & socket->accepted ); |
147 | socket_cores_exclude( local_sockets, socket_id ); |
155 | socket_cores_exclude( local_sockets, socket_id ); |
148 | return EOK; |
156 | return EOK; |
149 | } |
157 | } |
150 | 158 | ||
151 | /** @} |
159 | /** @} |