patch-2.2.18 linux/net/sunrpc/svcsock.c
Next file: linux/net/sunrpc/sysctl.c
Previous file: linux/net/sunrpc/svc.c
Back to the patch index
Back to the overall index
- Lines: 159
- Date:
Thu Oct 19 01:13:04 2000
- Orig file:
v2.2.17/net/sunrpc/svcsock.c
- Orig date:
Fri Apr 21 12:47:17 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/net/sunrpc/svcsock.c linux/net/sunrpc/svcsock.c
@@ -344,8 +344,9 @@
return;
dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
svsk, sk, count, svsk->sk_busy);
- svsk->sk_data = 1;
+ svsk->sk_data++;
svc_sock_enqueue(svsk);
+ wake_up_interruptible(sk->sleep);
}
/*
@@ -358,19 +359,10 @@
struct svc_serv *serv = svsk->sk_server;
struct sk_buff *skb;
u32 *data;
- int err, len;
-
- svsk->sk_data = 0;
- while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
- svc_sock_received(svsk, 0);
- if (err == -EAGAIN)
- return err;
- /* possibly an icmp error */
- dprintk("svc: recvfrom returned error %d\n", -err);
- }
+ int err, len, recvd = svsk->sk_data;
- /* There may be more data */
- svsk->sk_data = 1;
+ if ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL)
+ goto out_err;
len = skb->len - sizeof(struct udphdr);
data = (u32 *) (skb->h.raw + sizeof(struct udphdr));
@@ -390,15 +382,24 @@
#else
rqstp->rq_addr.sin_addr.s_addr = skb->saddr;
#endif
+ memset(rqstp->rq_addr.sin_zero, 0, sizeof(rqstp->rq_addr.sin_zero));
if (serv->sv_stats)
serv->sv_stats->netudpcnt++;
/* One down, maybe more to go... */
svsk->sk_sk->stamp = skb->stamp;
- svc_sock_received(svsk, 0);
+ svc_sock_received(svsk, 1);
return len;
+ out_err:
+ if (err != -EAGAIN) {
+ /* possibly an icmp error */
+ dprintk("svc: recvfrom returned error %d\n", -err);
+ svc_sock_received(svsk, 0);
+ } else
+ svc_sock_received(svsk, recvd);
+ return -EAGAIN;
}
static int
@@ -458,6 +459,7 @@
}
svsk->sk_conn++;
svc_sock_enqueue(svsk);
+ wake_up_interruptible(sk->sleep);
}
/*
@@ -477,6 +479,7 @@
}
svsk->sk_close = 1;
svc_sock_enqueue(svsk);
+ wake_up_interruptible(sk->sleep);
}
static void
@@ -548,15 +551,18 @@
/* Ideally, we would want to reject connections from unauthorized
* hosts here, but we have no generic client tables. For now,
- * we just punt connects from unprivileged ports. */
- if (ntohs(sin.sin_port) >= 1024) {
- if (net_ratelimit())
- printk(KERN_WARNING
- "%s: connect from unprivileged port: %s:%d",
- serv->sv_name,
- in_ntoa(sin.sin_addr.s_addr), ntohs(sin.sin_port));
- goto failed;
- }
+ * we just punt connects from unprivileged ports.
+ * hosts here, but when we get encription, the IP of the host won't
+ * tell us anything. For now just warn about unpriv connections.
+ */
+ if (ntohs(sin.sin_port) >= 1024) {
+ if (net_ratelimit())
+ printk(KERN_WARNING
+ "%s: connect from unprivileged port: %u.%u.%u.%u:%d\n",
+ serv->sv_name,
+ NIPQUAD(sin.sin_addr.s_addr),
+ ntohs(sin.sin_port));
+ }
dprintk("%s: connect from %s:%04x\n", serv->sv_name,
in_ntoa(sin.sin_addr.s_addr), ntohs(sin.sin_port));
@@ -590,7 +596,7 @@
struct svc_sock *svsk = rqstp->rq_sock;
struct svc_serv *serv = svsk->sk_server;
struct svc_buf *bufp = &rqstp->rq_argbuf;
- int len, ready;
+ int len, ready, used;
dprintk("svc: tcp_recv %p data %d conn %d close %d\n",
svsk, svsk->sk_data, svsk->sk_conn, svsk->sk_close);
@@ -624,10 +630,11 @@
svsk->sk_reclen = ntohl(svsk->sk_reclen);
if (!(svsk->sk_reclen & 0x80000000)) {
- /* FIXME: shutdown socket */
- printk(KERN_NOTICE "RPC: bad TCP reclen %08lx",
- (unsigned long) svsk->sk_reclen);
- return -EIO;
+ if (net_ratelimit())
+ printk(KERN_NOTICE "RPC: bad TCP reclen %08lx",
+ (unsigned long) svsk->sk_reclen);
+ svc_delete_socket(svsk);
+ return 0;
}
svsk->sk_reclen &= 0x7fffffff;
dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
@@ -642,8 +649,19 @@
dprintk("svc: incomplete TCP record (%d of %d)\n",
len, svsk->sk_reclen);
svc_sock_received(svsk, ready);
- len = -EAGAIN; /* record not complete */
+ return -EAGAIN; /* record not complete */
+ }
+
+ /* if we think there is only one more record to read, but
+ * it is bigger than we expect, then two records must have arrived
+ * together, so pretend we aren't using the record.. */
+ if (len > svsk->sk_reclen && ready == 1){
+ used = 0;
+ dprintk("svc_recv: more data at hte socket len %d > svsk->sk_reclen %d",
+ len, svsk->sk_reclen);
}
+ else used = 1;
+
/* Frob argbuf */
bufp->iov[0].iov_base += 4;
@@ -670,7 +688,7 @@
svsk->sk_reclen = 0;
svsk->sk_tcplen = 0;
- svc_sock_received(svsk, 1);
+ svc_sock_received(svsk, used);
if (serv->sv_stats)
serv->sv_stats->nettcpcnt++;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)