48,13 → 48,13 |
|
#include "socket_core.h" |
|
int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port ); |
|
INT_MAP_IMPLEMENT( socket_cores, socket_core_t ); |
|
INT_MAP_IMPLEMENT( socket_ports, socket_core_ref ); |
|
int socket_bind( socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen ){ |
ERROR_DECLARE; |
|
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 ){ |
socket_core_ref socket; |
socket_core_ref * socket_pointer; |
struct sockaddr * address; |
69,6 → 69,10 |
// find the socket |
socket = socket_cores_find( local_sockets, socket_id ); |
if( ! socket ) return ENOTSOCK; |
// bind a free port? |
if( address_in->sin_port <= 0 ){ |
return socket_bind_free_port( global_sockets, socket, free_ports_start, free_ports_end, last_used_port ); |
} |
// try to find the port |
socket_pointer = socket_ports_find( global_sockets, address_in->sin_port ); |
if( socket_pointer ){ |
77,21 → 81,58 |
} |
// disbind if bound |
socket_ports_exclude( global_sockets, socket->port ); |
socket->port = -1; |
return socket_bind_insert( global_sockets, socket, address_in->sin_port ); |
break; |
// TODO IPv6 |
default: |
return EAFNOSUPPORT; |
} |
return EOK; |
} |
|
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 ){ |
int index; |
|
// from the last used one |
index = last_used_port; |
do{ |
++ index; |
// til the range end |
if( index >= free_ports_end ){ |
// start from the range beginning |
index = free_ports_start - 1; |
do{ |
++ index; |
// til the last used one |
if( index >= last_used_port ){ |
// none found |
return ENOTCONN; |
} |
}while( socket_ports_find( global_sockets, index ) != NULL ); |
// found, break immediately |
break; |
} |
}while( socket_ports_find( global_sockets, index ) != NULL ); |
return socket_bind_insert( global_sockets, socket, index ); |
} |
|
int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port ){ |
ERROR_DECLARE; |
|
socket_core_ref * socket_pointer; |
|
// create a wrapper |
socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer )); |
if( ! socket_pointer ) return ENOMEM; |
* socket_pointer = socket; |
// register the port |
ERROR_CODE = socket_ports_add( global_sockets, address_in->sin_port, socket_pointer ); |
// register the incomming port |
ERROR_CODE = socket_ports_add( global_sockets, port, socket_pointer ); |
if( ERROR_CODE < 0 ){ |
free( socket_pointer ); |
return ERROR_CODE; |
} |
socket->port = address_in->sin_port; |
break; |
// TODO IPv6 |
default: |
return EAFNOSUPPORT; |
} |
socket->port = port; |
return EOK; |
} |
|