File tftp-get_dst_address.patch of Package tftp.openSUSE_12.1_Update
Index: tftp-hpa-git-0.48/tftpd/recvfrom.c
===================================================================
--- tftp-hpa-git-0.48.orig/tftpd/recvfrom.c 2008-07-31 12:46:57.000000000 +0200
+++ tftp-hpa-git-0.48/tftpd/recvfrom.c 2012-08-21 21:23:29.729823813 +0200
@@ -81,6 +81,14 @@ static int address_is_local(const union
if (sockfd < 0)
goto err;
+
+ /* check if we can bind to that address */
+ if (bind(sockfd, &addr->sa, SOCKLEN(addr)) == 0) {
+ /* success -> stop the testing */
+ rv = 1;
+ goto err;
+ }
+
if (connect(sockfd, &addr->sa, SOCKLEN(addr)))
goto err;
@@ -88,6 +96,10 @@ static int address_is_local(const union
if (getsockname(sockfd, (struct sockaddr *)&sa, &addrlen))
goto err;
+ /* if the request came via a secondary address,
+ * the following tests fail, because connect
+ * binds to the primary address for datagram sockets
+ */
if (addr->sa.sa_family == AF_INET)
rv = sa.si.sin_addr.s_addr == addr->si.sin_addr.s_addr;
#ifdef HAVE_IPV6
@@ -142,16 +154,13 @@ myrecvfrom(int s, void *buf, int len, un
/* Try to enable getting the return address */
#ifdef IP_RECVDSTADDR
- if (from->sa_family == AF_INET)
setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on));
#endif
#ifdef IP_PKTINFO
- if (from->sa_family == AF_INET)
setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
#endif
#ifdef HAVE_IPV6
#ifdef IPV6_RECVPKTINFO
- if (from->sa_family == AF_INET6)
setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
#endif
#endif
@@ -160,6 +169,7 @@ myrecvfrom(int s, void *buf, int len, un
msg.msg_controllen = sizeof(control_un);
msg.msg_flags = 0;
+ /* note: from is not initialized when receiving first request */
msg.msg_name = from;
msg.msg_namelen = *fromlen;
iov.iov_base = buf;