Rev 4603 | Rev 4704 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4603 | Rev 4700 | ||
---|---|---|---|
Line 46... | Line 46... | ||
46 | #include "../structures/packet/packet.h" |
46 | #include "../structures/packet/packet.h" |
47 | #include "../structures/packet/packet_client.h" |
47 | #include "../structures/packet/packet_client.h" |
48 | 48 | ||
49 | #include "socket_core.h" |
49 | #include "socket_core.h" |
50 | 50 | ||
- | 51 | int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port ); |
|
- | 52 | ||
51 | INT_MAP_IMPLEMENT( socket_cores, socket_core_t ); |
53 | INT_MAP_IMPLEMENT( socket_cores, socket_core_t ); |
52 | 54 | ||
53 | INT_MAP_IMPLEMENT( socket_ports, socket_core_ref ); |
55 | INT_MAP_IMPLEMENT( socket_ports, socket_core_ref ); |
54 | 56 | ||
55 | int socket_bind( socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen ){ |
57 | 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 ){ |
56 | ERROR_DECLARE; |
- | |
57 | - | ||
58 | socket_core_ref socket; |
58 | socket_core_ref socket; |
59 | socket_core_ref * socket_pointer; |
59 | socket_core_ref * socket_pointer; |
60 | struct sockaddr * address; |
60 | struct sockaddr * address; |
61 | struct sockaddr_in * address_in; |
61 | struct sockaddr_in * address_in; |
62 | 62 | ||
Line 67... | Line 67... | ||
67 | if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
67 | if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
68 | address_in = ( struct sockaddr_in * ) addr; |
68 | address_in = ( struct sockaddr_in * ) addr; |
69 | // find the socket |
69 | // find the socket |
70 | socket = socket_cores_find( local_sockets, socket_id ); |
70 | socket = socket_cores_find( local_sockets, socket_id ); |
71 | if( ! socket ) return ENOTSOCK; |
71 | if( ! socket ) return ENOTSOCK; |
- | 72 | // bind a free port? |
|
- | 73 | if( address_in->sin_port <= 0 ){ |
|
- | 74 | return socket_bind_free_port( global_sockets, socket, free_ports_start, free_ports_end, last_used_port ); |
|
- | 75 | } |
|
72 | // try to find the port |
76 | // try to find the port |
73 | socket_pointer = socket_ports_find( global_sockets, address_in->sin_port ); |
77 | socket_pointer = socket_ports_find( global_sockets, address_in->sin_port ); |
74 | if( socket_pointer ){ |
78 | if( socket_pointer ){ |
75 | // already used |
79 | // already used |
76 | return EADDRINUSE; |
80 | return EADDRINUSE; |
77 | } |
81 | } |
78 | // disbind if bound |
82 | // disbind if bound |
79 | socket_ports_exclude( global_sockets, socket->port ); |
83 | socket_ports_exclude( global_sockets, socket->port ); |
80 | // create a wrapper |
- | |
81 | socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer )); |
- | |
82 | if( ! socket_pointer ) return ENOMEM; |
- | |
83 | * socket_pointer = socket; |
84 | socket->port = -1; |
84 | // register the port |
- | |
85 | ERROR_CODE = socket_ports_add( global_sockets, address_in->sin_port, socket_pointer ); |
85 | return socket_bind_insert( global_sockets, socket, address_in->sin_port ); |
86 | if( ERROR_CODE < 0 ){ |
- | |
87 | free( socket_pointer ); |
- | |
88 | } |
- | |
89 | socket->port = address_in->sin_port; |
- | |
90 | break; |
86 | break; |
91 | // TODO IPv6 |
87 | // TODO IPv6 |
92 | default: |
88 | default: |
93 | return EAFNOSUPPORT; |
89 | return EAFNOSUPPORT; |
94 | } |
90 | } |
95 | return EOK; |
91 | return EOK; |
96 | } |
92 | } |
97 | 93 | ||
- | 94 | 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 ){ |
|
- | 95 | int index; |
|
- | 96 | ||
- | 97 | // from the last used one |
|
- | 98 | index = last_used_port; |
|
- | 99 | do{ |
|
- | 100 | ++ index; |
|
- | 101 | // til the range end |
|
- | 102 | if( index >= free_ports_end ){ |
|
- | 103 | // start from the range beginning |
|
- | 104 | index = free_ports_start - 1; |
|
- | 105 | do{ |
|
- | 106 | ++ index; |
|
- | 107 | // til the last used one |
|
- | 108 | if( index >= last_used_port ){ |
|
- | 109 | // none found |
|
- | 110 | return ENOTCONN; |
|
- | 111 | } |
|
- | 112 | }while( socket_ports_find( global_sockets, index ) != NULL ); |
|
- | 113 | // found, break immediately |
|
- | 114 | break; |
|
- | 115 | } |
|
- | 116 | }while( socket_ports_find( global_sockets, index ) != NULL ); |
|
- | 117 | return socket_bind_insert( global_sockets, socket, index ); |
|
- | 118 | } |
|
- | 119 | ||
- | 120 | int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port ){ |
|
- | 121 | ERROR_DECLARE; |
|
- | 122 | ||
- | 123 | socket_core_ref * socket_pointer; |
|
- | 124 | ||
- | 125 | // create a wrapper |
|
- | 126 | socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer )); |
|
- | 127 | if( ! socket_pointer ) return ENOMEM; |
|
- | 128 | * socket_pointer = socket; |
|
- | 129 | // register the incomming port |
|
- | 130 | ERROR_CODE = socket_ports_add( global_sockets, port, socket_pointer ); |
|
- | 131 | if( ERROR_CODE < 0 ){ |
|
- | 132 | free( socket_pointer ); |
|
- | 133 | return ERROR_CODE; |
|
- | 134 | } |
|
- | 135 | socket->port = port; |
|
- | 136 | return EOK; |
|
- | 137 | } |
|
- | 138 | ||
98 | int socket_create( socket_cores_ref local_sockets, int app_phone, int * socket_id ){ |
139 | int socket_create( socket_cores_ref local_sockets, int app_phone, int * socket_id ){ |
99 | ERROR_DECLARE; |
140 | ERROR_DECLARE; |
100 | 141 | ||
101 | socket_core_ref socket; |
142 | socket_core_ref socket; |
102 | int res; |
143 | int res; |