aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcsock.c
diff options
context:
space:
mode:
authorFrank van Maarseveen <frankvm@frankvm.com>2007-07-09 16:21:39 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-10 23:40:49 -0400
commita97476926ec061f90b77da478620ea6dc71a3237 (patch)
tree0b6ad42f5cca4484ce702cf3fcb016b52ec17cef /net/sunrpc/svcsock.c
parent96802a095171f5b35cf0e1e0d4be943e6696a253 (diff)
SUNRPC server: record the destination address of a request
Save the destination address of an incoming request over TCP like is done already for UDP. It is necessary later for callbacks by the server. Signed-off-by: Frank van Maarseveen <frankvm@frankvm.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r--net/sunrpc/svcsock.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 5baf48de2558..64b9b8c743c4 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -644,6 +644,7 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
644 struct msghdr msg = { 644 struct msghdr msg = {
645 .msg_flags = MSG_DONTWAIT, 645 .msg_flags = MSG_DONTWAIT,
646 }; 646 };
647 struct sockaddr *sin;
647 int len; 648 int len;
648 649
649 len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen, 650 len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen,
@@ -654,6 +655,19 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
654 memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen); 655 memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen);
655 rqstp->rq_addrlen = svsk->sk_remotelen; 656 rqstp->rq_addrlen = svsk->sk_remotelen;
656 657
658 /* Destination address in request is needed for binding the
659 * source address in RPC callbacks later.
660 */
661 sin = (struct sockaddr *)&svsk->sk_local;
662 switch (sin->sa_family) {
663 case AF_INET:
664 rqstp->rq_daddr.addr = ((struct sockaddr_in *)sin)->sin_addr;
665 break;
666 case AF_INET6:
667 rqstp->rq_daddr.addr6 = ((struct sockaddr_in6 *)sin)->sin6_addr;
668 break;
669 }
670
657 dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n", 671 dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
658 svsk, iov[0].iov_base, iov[0].iov_len, len); 672 svsk, iov[0].iov_base, iov[0].iov_len, len);
659 673
@@ -1064,6 +1078,12 @@ svc_tcp_accept(struct svc_sock *svsk)
1064 goto failed; 1078 goto failed;
1065 memcpy(&newsvsk->sk_remote, sin, slen); 1079 memcpy(&newsvsk->sk_remote, sin, slen);
1066 newsvsk->sk_remotelen = slen; 1080 newsvsk->sk_remotelen = slen;
1081 err = kernel_getsockname(newsock, sin, &slen);
1082 if (unlikely(err < 0)) {
1083 dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err);
1084 slen = offsetof(struct sockaddr, sa_data);
1085 }
1086 memcpy(&newsvsk->sk_local, sin, slen);
1067 1087
1068 svc_sock_received(newsvsk); 1088 svc_sock_received(newsvsk);
1069 1089