服务器处于SSL_read时来自客户端的SSL_connect

时间:2019-02-16 22:50:57

标签: c sockets ssl openssl tls1.2

我有一个非阻塞套接字,并使用select处理来自多个SSL客户端的连接:

我已经尝试过有关处理SSL_ERROR_WANT_READ的建议,例如重复SSL_read调用,或者返回到Select,但是对于我来说似乎不起作用。

while (1)
   {
   start:      
      if (readyCount = select(FD_SETSIZE, &read_fd_set, NULL, NULL, &timeout) < 0)
      {
         exit(EXIT_FAILURE);
      }
      for (int i = 0; i < FD_SETSIZE; ++i)
         if (FD_ISSET(i, &read_fd_set))
         {
            if (i == sockfd)
            {               
               newSocket = accept(sockfd, (struct sockaddr *) &clientname, (socklen_t*)&size);                              
            }
            else
            {
               ssl = SSL_new(ctx);
               SSL_set_fd(ssl, i);
            accept:
               int err = SSL_accept(ssl);
               if (0 >= err)
               {                    // it never goes here 
                  int resultCode = SSL_get_error(ssl, err);
                  switch (resultCode)
                  {                 
                     case SSL_ERROR_NONE:
                        goto accept;
                        break;
                     case SSL_ERROR_ZERO_RETURN:
                        SSL_shutdown(ssl);                        
                        break;
                     case SSL_ERROR_SYSCALL:                     
                        break;
                     case SSL_ERROR_WANT_READ:
                        break;
                     case SSL_ERROR_WANT_WRITE:
                        break;
                     case SSL_ERROR_WANT_CONNECT:
                        break;
                     case SSL_ERROR_WANT_ACCEPT:
                        goto accept;
                        break;
                     case SSL_ERROR_WANT_X509_LOOKUP:
                        break;
                     case SSL_ERROR_SSL:
                        break;                     }
                     default:
                        break;
                  }
               }
               else
               {
                  Call_Read(...)
               }

               SSL_free(ssl);
               close(i);
               FD_CLR(i, &active_fd_set);
            }
         }
   }   


Call_Read(...)
{   
   int fd = SSL_get_fd(ssl);
   fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);

   while (data_size > 0)
   {
      bytes_recv = SSL_read(ssl, data, data_size);
      if (bytes_recv <= 0)
      {
         if (SSL_ERROR_WANT_READ == SSL_get_error(ssl, bytes_recv))
         {
            testtt = SSL_pending(ssl); //always 0
            /*SSL_renegotiate(ssl);
            SSL_do_handshake(ssl);*/
            continue;
         }
         if (SSL_ERROR_WANT_WRITE == SSL_get_error(ssl, bytes_recv))
         {            
            testtt = SSL_pending(ssl);
            int blocked_on_SSL_ERROR_WANT_WRITE = 1;                        
            continue;         }
         }
         return bytes_recv;
      }

      data += bytes_recv;
      data_size -= bytes_recv;
   }
   return 1;
}

Client Write:
{
while (data_size > 0)
      {
         bytes_sent = SSL_write(ssl, data_ptr, data_size);
         if (errno == EPIPE) == doesn’t reach this line, debugger stops with EPIPE
         {
            printf("WRITE socket returned EPIPE”);
            return -1;
         }

         if (bytes_sent < 0)
         {
            int err = SSL_get_error(ssl, bytes_sent);
            switch (err)
            {
               case SSL_ERROR_WANT_READ:
                  printf(" SSL_ERROR_WANT_READ\n");
               case SSL_ERROR_WANT_WRITE:
                  printf(" SSL_ERROR_WANT_WRITE\n");
               default:
                  ;
            }
         }         

         data_ptr += bytes_sent;
         data_size -= bytes_sent;
      }

      return 1;
   }

当服务器处于SSL_Read且某些客户端调用SSL_Connect时,我不知道该如何处理。

在这种情况下,对于SSL_ERROR_WANT_READ,Call_Read将处于无限循环中。如果我将“ continue”语句替换为将结束循环的标志,并且调用者返回“ Select”,则客户端将因管道错误而中断,甚至不会到达“ WRITE socket returned EPIPE”行。如果我从读取循环返回到Accept而不是Select,也会发生同样的情况。

我在这里缺少一些东西,我想知道是否也应该对客户端进行一些更改。 有什么建议吗?

0 个答案:

没有答案