重新启动UDP套接字以接受DTLS连接不起作用

时间:2014-07-21 08:07:19

标签: c udp winsockets dtls

我正在启动UDP服务器,然后接受DTLS连接以读取传入数据。代码工作正常。但是,一旦我通过重新启动客户端套接字从客户端重用连接,服务器就无法读取任何内容。使用Cyassl库创建SSL实例。

在客户中: 套接字绑定和DTLS初始化很好,因为它重新使用之前使用的DTLS上下文。

在服务器中: 插座关闭和启动一切都很好,但我仍然无法接收到已接受的FD。

但是,如果我在关闭和启动UDP服务器之间完成5秒的睡眠,一切都很好。但我不想像睡眠一样使用阻塞I / O.

请帮忙。 服务器:

接受m_udp_fd中收到的数据:

    if(FD_ISSET(m_udp_fd, &rfds))
    {
        if(m_accepted_flag==0)
        {
            udp_read_connect(m_udp_fd);
            open_dtls_server();
            if(m_ssl_accept(m_udp_fd)>0)
            {
                media_accepted_flag = 1;
            }
        }
        else 
        {
                // Read data
                if(process_dtls_packet(m_udp_fd)<=0)
                {
                    //Clear FD here
                }
        }   

    }

断开连接的位置取决于TCP连接是否断开。 这完全受到了打击:

    if (FD_ISSET(m_fd, &rfds))
    {
         if(process_msg(m_fd)<=0)
         {
             closesocket(m_fd);
             FD_CLR(m_fd,recv_fds);
             if(recv_fdmax == m_fd)
             {
                    recv_fdmax = max(x_fd,y_fd);
                    recv_fdmax = max(recv_fdmax,z_fd);
                    recv_fdmax = max(recv_fdmax,p_fd);
                    recv_fdmax = max(recv_fdmax,q_fd);
             }
         }

         if(m_accepted_flag!=0)
         {
                m_accepted_flag = 0;
                x_accepted_flag = 0;
                //This sleep when kept works perfectly
                Sleep(5000);
                close_m_and_x_connection(&recv_fdmax,recv_fds,&m_udp_fd,&x_udp_fd);
         }
    }

UDP读取连接功能:

    int udp_read_connect(SOCKET sockfd)
    {
         struct sockaddr cliaddr;
         char          b[1500];
         int           n;
         int     len = sizeof(cliaddr);

         n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
                  (struct sockaddr*)&cliaddr, &len);
        if (n > 0) 
        {
              if (connect(sockfd, (const struct sockaddr*)&cliaddr,sizeof(cliaddr)) != 0)
              printf("udp connect failed");
        }
        else
              printf("recvfrom failed");

        return sockfd;
     }

打开DTLS服务器方法:这里dtls_ctx和dtls_meth是全局变量。

    int open_dtls_server()
    {
        int verify_flag = OFF;       
        int error;

        if(dtls_ctx!= NULL)
            return;

        dtls_ctx  = ssl_create_context(DTLS_V1, &dtls_meth);
        dtls_meth = CyaDTLSv1_server_method();
        if(dtls_meth==NULL)
        {
            return -1;
        }

        dtls_ctx = CyaSSL_CTX_new(dtls_meth);

        if(NULL == dtls_ctx)
        {
           ERR_print_errors_fp(stderr);
           return -1;
        }

       if((status   =   LoadSSLCertificate(dtls_ctx,sslInfo,&error,0)) == 1)
       {
             return 0;
       }
       else
             return 1;

       if(CyaSSL_CTX_use_PrivateKey_file(dtls_ctx, SSL_SERVER_RSA_KEY, SSL_FILETYPE_PEM) <= 0)  
       {
            ERR_print_errors_fp(stderr);
            return -1;      
       }

       if(CyaSSL_CTX_check_private_key(dtls_ctx) != 1)
       {
            return -1;
       }    
       if(verify_flag)
       {    
           if(!CyaSSL_CTX_load_verify_locations(dtls_ctx, SSL_SERVER_RSA_CA_CERT, NULL))
           {
                ERR_print_errors_fp(stderr);
                return -1;      
           }
            CyaSSL_CTX_set_verify(dtls_ctx, SSL_VERIFY_PEER, NULL);
       }

       CyaSSL_CTX_set_options(dtls_ctx, SSL_OP_ALL);
       return 1;
   }

m_ssl_accept功能:ssl_m也是一个全局变量。

    int m_ssl_accept(int confd)
    {
        int ret;
        if(ssl_m==NULL)
        {
            ssl_m = CyaSSL_new(dtls_ctx);

            if (ssl_m == NULL) 
              printf("SSL_new failed");

            CyaSSL_set_fd(ssl_m, confd);
        }

        do
        {
              if((ret = CyaSSL_accept(ssl_m))!= 1)
              {
                   printf("Handshake Error on M Channel %d with FD: [%d]\n", 
                   return -1;
              }

        }while(ret != 1);

        return 1;
    }

0 个答案:

没有答案