+ if (sotype == SOCK_STREAM) {
+ int maxretries = 60;
+ struct iovec_32 aio;
+ aio.iov_base = (uintptr_t) &len;
+ aio.iov_len = sizeof(u_long);
+ bzero(&msg, sizeof(msg));
+ msg.msg_iov = (struct iovec *) &aio;
+ msg.msg_iovlen = 1;
+ do {
+ error = sock_receive(so, &msg, MSG_WAITALL, &readlen);
+ if ((error == EWOULDBLOCK) && (--maxretries <= 0))
+ error = ETIMEDOUT;
+ } while (error == EWOULDBLOCK);
+ if (!error && readlen < aio.iov_len) {
+ /* only log a message if we got a partial word */
+ if (readlen != 0)
+ printf("short receive (%d/%d) from server " IP_FORMAT "\n",
+ readlen, sizeof(u_long), IP_LIST(&(sin->sin_addr.s_addr)));
+ error = EPIPE;
+ }
+ if (error)
+ goto out;
+ len = ntohl(len) & ~0x80000000;
+ /*
+ * This is SERIOUS! We are out of sync with the sender
+ * and forcing a disconnect/reconnect is all I can do.
+ */
+ if (len > maxpacket) {
+ printf("impossible packet length (%d) from server %s\n",
+ len, IP_LIST(&(sin->sin_addr.s_addr)));
+ error = EFBIG;
+ goto out;
+ }
+
+ do {
+ readlen = len;
+ error = sock_receivembuf(so, NULL, &m, MSG_WAITALL, &readlen);
+ } while (error == EWOULDBLOCK);
+
+ if (!error && (len > (int)readlen)) {
+ printf("short receive (%d/%d) from server %s\n",
+ readlen, len, IP_LIST(&(sin->sin_addr.s_addr)));
+ error = EPIPE;
+ }
+ } else {
+ len = maxpacket;
+ readlen = len;
+ bzero(&msg, sizeof(msg));
+ msg.msg_name = from_p;
+ msg.msg_namelen = (from_p == NULL) ? 0 : sizeof(*from_p);
+ error = sock_receivembuf(so, &msg, &m, 0, &readlen);
+ }