I'm attempting to configure my SSL sockets to manage multiple connections using 'select()', however I've been unable to get it working. Currently the connections are being accepted, however they are blocking, therefore the server can only handle reading each request at a time.
Code:
int main(int argc, char **argv)
{
int sock;
SSL_CTX *ctx;
init_openssl(); //Load dependencies
ctx = create_context(); //Set Protocol
configure_context(ctx); //Set key/cert
sock = create_socket(3000); //Configure and bind listener
fd_set active_fd_set, read_fd_set;
timeval t;
FD_ZERO(&active_fd_set); //initialise fd active
FD_SET(sock,&active_fd_set); //includes sock in the fd
while(1)
{
int i;
struct sockaddr_in addr;
uint len = sizeof(addr);
SSL *ssl;
read_fd_set=active_fd_set;
if(select(FD_SETSIZE,&read_fd_set,NULL,NULL,NULL)<0)
{
std::cout<<"Error at select!"<<std::endl;
}
for(i=0;i<FD_SETSIZE;i++)
{
if(FD_ISSET(i,&read_fd_set)) //Is fd part of the set
{
if(i==sock)
{
int client = accept(sock,(struct sockaddr*)&addr,&len);
if(client>0){std::cout<<"Client accepted"<<std::endl;}else{std::cout<<"Client failed"<<std::endl;}
ssl = SSL_new(ctx); //Create new ssl structure for connection
SSL_set_fd(ssl, client);
FD_SET(client,&active_fd_set);
if(SSL_accept(ssl)>0)
{
std::cout<<"ACCEPTED"<<std::endl;
}
}
else
{
if(SSL_accept(ssl)>0)
{
std::cout<<"Down here"<<std::endl;
close(i);
FD_CLR(i,&active_fd_set);
}
}
}
}
}
Does anyone have any tips on how to get select() working?
First read SSL_accept(). Second use non-blocking BIO before calling SSL_accept().
Third, once you use non-blocking BIO, you should add the accepted connection sockets (client in your case) to select call and take action only if there is any activity on client socket. You will have to maintain state in that case.
Your current implementation is DOS attack prone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With