Winsock handles SO_RCVTIMEO in unique manner...
[openssl.git] / crypto / bio / bss_dgram.c
index a0cb29b3dcee8e74546ca9437d2ea481ff08454e..1d203aeec554f77f27bbf86e14361364db092672 100644 (file)
@@ -82,7 +82,7 @@ static int dgram_new(BIO *h);
 static int dgram_free(BIO *data);
 static int dgram_clear(BIO *bio);
 
-int BIO_dgram_should_retry(int s);
+static int BIO_dgram_should_retry(int s);
 
 static BIO_METHOD methods_dgramp=
        {
@@ -208,9 +208,13 @@ static int dgram_write(BIO *b, const char *in, int inl)
        clear_socket_error();
 
     if ( data->connected )
-        ret=send(b->num,in,inl,0);
+        ret=writesocket(b->num,in,inl);
     else
+#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
+        ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer));
+#else
         ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer));
+#endif
 
        BIO_clear_retry_flags(b);
        if (ret <= 0)
@@ -341,30 +345,90 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 
         memcpy(&(data->peer), to, sizeof(struct sockaddr));
         break;
+#if defined(SO_RCVTIMEO)
        case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+               {
+               struct timeval *tv = (struct timeval *)ptr;
+               int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
+               if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIME0,
+                       (void*)&timeout, sizeof(timeout)) < 0)
+                       { perror("setsockopt"); ret = -1; }
+               }
+#else
                if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
                        sizeof(struct timeval)) < 0)
                        { perror("setsockopt"); ret = -1; }
+#endif
                break;
        case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+               {
+               int timeout, sz = sizeof(timeout);
+               struct timeval *tv = (struct timeval *)ptr;
+               if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIME0,
+                       (void*)&timeout, &sz)) < 0)
+                       { perror("getsockopt"); ret = -1; }
+               else
+                       {
+                       tv->tv_sec = timeout / 1000;
+                       tv->tv_usec = (timeout % 1000) * 1000;
+                       ret = sizeof(*tv);
+                       }
+               }
+#else
                if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
                        ptr, (void *)&ret) < 0)
                        { perror("getsockopt"); ret = -1; }
+#endif
                break;
+#endif
+#if defined(SO_SNDTIMEO)
        case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+               {
+               struct timeval *tv = (struct timeval *)ptr;
+               int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
+               if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIME0,
+                       (void*)&timeout, sizeof(timeout)) < 0)
+                       { perror("setsockopt"); ret = -1; }
+               }
+#else
                if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
                        sizeof(struct timeval)) < 0)
                        { perror("setsockopt"); ret = -1; }
+#endif
                break;
        case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+               {
+               int timeout, sz = sizeof(timeout);
+               struct timeval *tv = (struct timeval *)ptr;
+               if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIME0,
+                       (void*)&timeout, &sz)) < 0)
+                       { perror("getsockopt"); ret = -1; }
+               else
+                       {
+                       tv->tv_sec = timeout / 1000;
+                       tv->tv_usec = (timeout % 1000) * 1000;
+                       ret = sizeof(*tv);
+                       }
+               }
+#else
                if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 
                        ptr, (void *)&ret) < 0)
                        { perror("getsockopt"); ret = -1; }
+#endif
                break;
+#endif
        case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
                /* fall-through */
        case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+#ifdef OPENSSL_SYS_WINDOWS
+               if ( data->_errno == ETIMEDOUT)
+#else
                if ( data->_errno == EAGAIN)
+#endif
                        {
                        ret = 1;
                        data->_errno = 0;
@@ -399,7 +463,7 @@ static int dgram_puts(BIO *bp, const char *str)
        return(ret);
        }
 
-int BIO_dgram_should_retry(int i)
+static int BIO_dgram_should_retry(int i)
        {
        int err;