2014-06-12 8 views
7

send और receive जैसे सॉकेट फ़ंक्शन सिग्नल द्वारा बाधित किए जा सकते हैं। इसके कारण कुछ अतिरिक्त कोड की आवश्यकता है, उदा। errno == EINTR के लिए जांचें। यह संबंधित मैन पेजों पर वर्णित है।ओपनएसएसएल और संकेत

मुझे आश्चर्य है कि यह कैसे काम करता है जब OpenSSL फ़ंक्शंस का उपयोग किया जाता है, उदा। SSL_write, SSL_read। उनके मैन पेज सिग्नल के बारे में कुछ नहीं कहते हैं। मैंने इसके लिए भी Google की कोशिश की, लेकिन भाग्य के बिना। क्या आपको पता है कि ओपनएसएसएल आंतरिक रूप से संकेतों को संभालता है, या कुछ अतिरिक्त कोड की आवश्यकता है? यदि हां, तो कैसे जांचें कि सिग्नल द्वारा फ़ंक्शन कॉल बाधित किया गया था या नहीं?

अद्यतन:

लग रहा है कि OpenSSL पुनः संभाल नहीं करता है। यह केवल बीआईओ ऑब्जेक्ट पर "पुनः प्रयास करना" ध्वज सेट करता है। तो मैं पता लगाने के लिए अगर कॉल बाधित किया गया था और फिर से प्रयास करें की जरूरत है कुछ इस तरह उपयोग करने की आवश्यकता:

int result = SSL_write(ssl, buff, length); 
if ((result < 0) && BIO_should_retry(SSL_get_wbio(ssl))) 
    // need to retry 

int result = SSL_read(ssl, buff, length); 
if ((result < 0) && BIO_should_retry(SSL_get_rbio(ssl))) 
    // need to retry 

उत्तर

3

एक libray OpenSSL जा रहा है कि कैसे संकेत इसे का उपयोग विशेष रूप से इस कार्यक्रम के द्वारा नियंत्रित किया जाता है पर किसी भी मान्यताओं नहीं कर सकते हैं। इसलिए इसे सिग्नल के स्वागत पर एक सिस्टम कॉल के मामले को संभालने की आवश्यकता है।

एक चेक read() को पुनः प्रयास करने के लिए यह समझ में आया कि क्या ओपनएसएसएल के अंदर लागू किया गया है।

BIO_should_retry() का उपयोग करें यदि BIO_read() (या BIO_write()) विफल रहा।

एक उदाहरण के लिए यहां पढ़ें: http://cvs.openssl.org/rlog?f=openssl/demos/bio/sconnect.c

कार्यान्वयन के प्रासंगिक कोड इस प्रकार है:

static int sock_read(BIO *b, char *out, int outl) 
    { 
    int ret=0; 

    if (out != NULL) 
      { 
      clear_socket_error(); 
      ret=readsocket(b->num,out,outl); 
      BIO_clear_retry_flags(b); 
      if (ret <= 0) 
        { 
        if (BIO_sock_should_retry(ret)) 
          BIO_set_retry_read(b); 
        } 
      } 
    return(ret); 
    } 

प्रासंगिक संदर्भित किया जाता कार्यों यहां हैं:

(get_last_socket_error() रिटर्न errno सबसे IXish प्लेटफार्मों पर)

int BIO_sock_should_retry(int i) 
    { 
    int err; 

    if ((i == 0) || (i == -1)) 
      { 
      err=get_last_socket_error(); 

#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ 
      if ((i == -1) && (err == 0)) 
        return(1); 
#endif 

      return(BIO_sock_non_fatal_error(err)); 
      } 
    return(0); 
    } 


int BIO_sock_non_fatal_error(int err) 
     { 
     switch (err) 
       { 
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) 
# if defined(WSAEWOULDBLOCK) 
     case WSAEWOULDBLOCK: 
# endif 

# if 0 /* This appears to always be an error */ 
# if defined(WSAENOTCONN) 
     case WSAENOTCONN: 
# endif 
# endif 
#endif 

#ifdef EWOULDBLOCK 
# ifdef WSAEWOULDBLOCK 
# if WSAEWOULDBLOCK != EWOULDBLOCK 
     case EWOULDBLOCK: 
# endif 
# else 
     case EWOULDBLOCK: 
# endif 
#endif 

#if defined(ENOTCONN) 
     case ENOTCONN: 
#endif 

#ifdef EINTR 
     case EINTR: 
#endif 

#ifdef EAGAIN 
# if EWOULDBLOCK != EAGAIN 
     case EAGAIN: 
# endif 
#endif 

#ifdef EPROTO 
     case EPROTO: 
#endif 

#ifdef EINPROGRESS 
     case EINPROGRESS: 
#endif 

#ifdef EALREADY 
     case EALREADY: 
#endif 
       return(1); 
       /* break; */ 
     default: 
       break; 
       } 
     return(0); 
     } 

विवरण देखने के लिए sock_read() यहां का निरीक्षण करने के लिए किया जा: http://cvs.openssl.org/rlog?f=openssl/crypto/bio/bss_sock.c

(स्रोतों का इस्तेमाल दांतेदार बनाना संस्करण 1.0.1e से है के साथ उद्धृत।)

संबंधित मुद्दे