shithub: opusfile

Download patch

ref: bb8cb7a3de5aedafea43bfc8160e4099f4c48680
parent: e88aa498b8e09d129583127aa40d6689d37a8f31
author: Timothy B. Terriberry <tterribe@xiph.org>
date: Sun Oct 14 07:31:08 EDT 2012

Fix some socket connection bugs.

The big one was that if the connect() call failed, it would loop
 forever (thanks to some code re-factoring, the loop was no longer
 advancing to the next address as originally designed).

--- a/src/http.c
+++ b/src/http.c
@@ -1381,6 +1381,7 @@
     if(addr==NULL)return OP_FALSE;
     if(connect(_fd,addr->ai_addr,addr->ai_addrlen)>=0)return 1;
     if(OP_LIKELY(errno==EINPROGRESS))return 0;
+    addr=addr->ai_next;
   }
 }
 
@@ -1437,8 +1438,8 @@
     if(OP_LIKELY(fds[pi].fd>=0)){
       if(OP_LIKELY(op_sock_set_nonblocking(fds[pi].fd,1)>=0)){
         ret=op_sock_connect_next(fds[pi].fd,addrs+pi,ai_family);
-        if(ret>1){
-          /*It succeeded right away, so stop.*/
+        if(OP_UNLIKELY(ret>0)){
+          /*It succeeded right away (technically possible), so stop.*/
           nprotos=pi+1;
           break;
         }
@@ -1462,10 +1463,12 @@
       /*Still waiting...*/
       if(!fds[pi].revents)continue;
       errlen=sizeof(err);
-      if(getsockopt(fds[pi].fd,SOL_SOCKET,SO_ERROR,&err,&errlen)>=0&&err==0){
-        /*Success!*/
-        break;
-      }
+      /*Some platforms will return the pending error in &err and return 0.
+        Otherwise will put it in errno and return -1.*/
+      ret=getsockopt(fds[pi].fd,SOL_SOCKET,SO_ERROR,&err,&errlen);
+      if(ret<0)err=errno;
+      /*Success!*/
+      if(err==0||err==EISCONN)break;
       /*Move on to the next address for this protocol.*/
       ai_family=addrs[pi]->ai_family;
       addrs[pi]=addrs[pi]->ai_next;