2014-06-12 8 views
7

sinyalleri send ve receive gibi soket işlevleri sinyallerle kesilebilir. Bundan dolayı, bazı ekstra kodlara ihtiyaç duyulmaktadır, örn. errno == EINTR için kontrol etmek. Bu, ilgili adam sayfalarında açıklanmıştır.OpenSSL ve

OpenSSL işlevleri kullanıldığında bunun nasıl çalıştığını merak ediyorum, ör. SSL_write, SSL_read. Adamların sayfaları, sinyaller hakkında bir şey söylemez. Bunun için google'ı da denedim, ama şanssız. OpenSSL'nin sinyalleri dahili olarak ele alıp almadığını mı yoksa bazı ekstra kodlara mı ihtiyaç duyduğunu biliyor musunuz? Eğer evet ise, işlev çağrısının sinyalle kesilip kesilmediğini nasıl kontrol edersiniz?

Güncelleme:

OpenSSL yeniden deneme işlemek etmediğini görünüyor. Sadece BIO nesnesinde "yeniden denemeli" bayrağını ayarlar. Bu yüzden çağrı kesildi ve yeniden deneme gerekiyorsa algılamak için böyle bir şey kullanmak gerekir:

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 

cevap

3

sinyalleri kullanarak belirli bir program tarafından işlenme şekliyle ilgili herhangi bir varsayımda yapamaz bir libray OpenSSL olmanın gibi. Bu yüzden bir sinyalin alınmasında araya giren bir sistem çağrısının durumunu ele almalıdır.

Başarısız bir read() yeniden denemek için anlamlı olup olmadığını bir OpenSSL içinde uygulanmış olup olmadığını kontrol edin.

BIO_read() (veya BIO_write()) başarısız olursa, BIO_should_retry() kullanın. bir örnek için

burada okuyun: http://cvs.openssl.org/rlog?f=openssl/demos/bio/sconnect.c

uygulanması en uygun kod aşağıda:

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); 
    } 

alakalı sevk fonksiyonları Buradasınız:

(get_last_socket_error() getiri çoğu IXish platformlarda errno)

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); 
     } 
01 Ayrıntılar sock_read() için bkzburada kontrol edilmesi: http://cvs.openssl.org/rlog?f=openssl/crypto/bio/bss_sock.c

(kullanılan girinti versiyonu 1.0.1e dan birlikte alıntılanan kaynaklar.)