aboutsummaryrefslogtreecommitdiff
path: root/net/dante/files
diff options
context:
space:
mode:
authorAnders Nordby <anders@FreeBSD.org>2009-01-19 00:00:51 +0000
committerAnders Nordby <anders@FreeBSD.org>2009-01-19 00:00:51 +0000
commit01ba08301329560ef8ea24773346b3495572c9fe (patch)
tree90e02a7accb0228121a72f1188edecb7c9057824 /net/dante/files
parent51134e07e4e1bf1eecb82da29d859432eaa75640 (diff)
downloadports-01ba08301329560ef8ea24773346b3495572c9fe.tar.gz
ports-01ba08301329560ef8ea24773346b3495572c9fe.zip
Notes
Diffstat (limited to 'net/dante/files')
-rw-r--r--net/dante/files/patch-sockd-getifa.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/net/dante/files/patch-sockd-getifa.c b/net/dante/files/patch-sockd-getifa.c
new file mode 100644
index 000000000000..d6c6eecf51a3
--- /dev/null
+++ b/net/dante/files/patch-sockd-getifa.c
@@ -0,0 +1,216 @@
+--- sockd/getifa.c.orig 2003-07-01 13:21:40.000000000 +0000
++++ sockd/getifa.c 2009-01-18 23:43:40.000000000 +0000
+@@ -58,6 +58,9 @@
+ * that will be selected by the OS to connect to that destination address.
+ *==========================================================================*/
+ #include <net/route.h> /* RTA_xxx constants */
++#if HAVE_ROUTEINFO_BSD
++#include <net/if_dl.h>
++#endif /* HAVE_ROUTEINFO_BSD */
+ #if HAVE_ROUTEINFO_LINUX
+ #include <asm/types.h>
+ #include <linux/netlink.h>
+@@ -233,9 +236,11 @@
+ pid_t pid;
+ struct rt_msghdr *rtm;
+ struct sockaddr *sa;
++ char *cp;
++ int i;
+ uid_t euid;
+ struct in_addr inaddr_none;
+- struct in_addr gwaddr;
++ struct sockaddr ifa;
+
+ inaddr_none.s_addr = htonl(INADDR_NONE);
+
+@@ -256,85 +261,123 @@
+ }
+
+ /*===================================================================
+- * Do until 2 consecutive RTM_GET return the same gateway address.
+- * The first calls may return router addresses in RTA_GATEWAY and
+- * those will not match any local external address.
++ * Do a RTM_GET to look up the gateway for the address.
++ * Extract the RTM_IFA from it, which is the source address used
++ * on that interface.
++ * The code is modeled after the code for route(8).
+ *==================================================================*/
++ /*===========================================================
++ * Build the necessary data structures to get routing info.
++ * The structures are:
++ * rt_msghdr - Specifies RTM_GET for getting routing table
++ * info
++ * sockaddr - contains the destination address
++ * sockaddr_dl - necessary for unkown reasons.
++ *==========================================================*/
++#define ROUNDUP(a) \
++ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
++#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
++
++
++ bzero(buf, sizeof(buf));
++ rtm = (struct rt_msghdr *) buf;
++ rtm->rtm_version = RTM_VERSION;
++ rtm->rtm_type = RTM_GET;
++ rtm->rtm_flags = RTF_UP | RTF_HOST | RTF_GATEWAY | RTF_STATIC;
++ rtm->rtm_addrs = RTA_DST | RTA_IFA;
++ rtm->rtm_pid = pid = getpid();
++ rtm->rtm_seq = SEQ;
++
++ cp = (char *) (rtm + 1);
++ sa = (struct sockaddr *) cp;
++ /* LINTED pointer casts may be troublesome */
++ TOIN(sa)->sin_family = AF_INET;
++ /* LINTED pointer casts may be troublesome */
++ TOIN(sa)->sin_addr = destaddr;
++ /* LINTED pointer casts may be troublesome */
++ TOIN(sa)->sin_port = htons(0);
++ sa->sa_len = sizeof(struct sockaddr_in);
++ ADVANCE(cp, sa);
++ sa = (struct sockaddr *) cp;
++ /* add dummy link layer address */
++ sa->sa_family = AF_LINK;
++ sa->sa_len = sizeof(struct sockaddr_dl);
++ ADVANCE(cp, sa);
++ sa = (struct sockaddr *) cp;
++ rtm->rtm_addrs |= RTA_IFP;
++
++ rtm->rtm_msglen = cp - buf;
++
++ /*===========================================================
++ * Send the request and get the response.
++ *==========================================================*/
++ if (write(sockfd, rtm, (size_t)rtm->rtm_msglen) != rtm->rtm_msglen) {
++ swarn("%s: write() to AF_ROUTE failed", function);
++ close(sockfd);
++ return inaddr_none;
++ }
++
+ do {
+- /*===========================================================
+- * Build the necessary data structures to get routing info.
+- * The structures are:
+- * rt_msghdr - Specifies RTM_GET for getting routing table
+- * info
+- * sockaddr - contains the destination address
+- *==========================================================*/
+-
+- bzero(buf, sizeof(buf));
+- rtm = (struct rt_msghdr *) buf;
+- rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
+- rtm->rtm_version = RTM_VERSION;
+- rtm->rtm_type = RTM_GET;
+- rtm->rtm_addrs = RTA_DST;
+- rtm->rtm_pid = pid = getpid();
+- rtm->rtm_seq = SEQ;
+-
+- sa = (struct sockaddr *) (rtm + 1);
+- /* LINTED pointer casts may be troublesome */
+- TOIN(sa)->sin_family = AF_INET;
+- /* LINTED pointer casts may be troublesome */
+- TOIN(sa)->sin_addr = destaddr;
+- /* LINTED pointer casts may be troublesome */
+- TOIN(sa)->sin_port = htons(0);
+-
+- /*===========================================================
+- * Send the request and get the response.
+- *==========================================================*/
+- if (write(sockfd, rtm, (size_t)rtm->rtm_msglen) != rtm->rtm_msglen) {
+- swarn("%s: write() to AF_ROUTE failed", function);
++ if (read(sockfd, rtm, sizeof(buf)) == -1) {
++ swarn("%s: read from AF_ROUTE failed", function);
+ close(sockfd);
+ return inaddr_none;
+ }
++ } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ
++ || rtm->rtm_pid != pid);
+
+- do {
+- if (read(sockfd, rtm, sizeof(buf)) == -1) {
+- swarn("%s: read from AF_ROUTE failed", function);
++ /*================================================================
++ * Iterate over the address structure extracting only the relevant
++ * addresses.
++ *===============================================================*/
++ cp = (char *) (rtm + 1);
++ sa = (struct sockaddr *) cp;
++
++ for (i=0; (i < RTAX_MAX) && (cp < buf + sizeof(buf)); i++) {
++ switch (i) {
++ case RTAX_GATEWAY:
++ if (!(rtm->rtm_addrs & RTA_GATEWAY)) {
++ slog(LOG_DEBUG, "%s: can't find gateway for %s, using defaultexternal",
++ function, inet_ntoa(destaddr));
+ close(sockfd);
+- return inaddr_none;
++ return getdefaultexternal();
+ }
+- } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ
+- || rtm->rtm_pid != pid);
+-
+- /*============================================================
+- * Go straight to the RTA_GATEWAY entry for our info.
+- *===========================================================*/
+- sa = (struct sockaddr *) (rtm + 1);
+-
+- if (!(rtm->rtm_addrs & RTA_GATEWAY)
+- || (sa += RTAX_GATEWAY) == NULL
+- || TOIN(sa)->sin_family != AF_INET) {
+- slog(LOG_DEBUG, "%s: can't find gateway for %s, using defaultexternal",
+- function, inet_ntoa(destaddr));
+- close(sockfd);
+- return getdefaultexternal();
++ break;
++ case RTAX_IFA:
++ if (!(rtm->rtm_addrs & RTA_IFA)
++ || TOIN(sa)->sin_family != AF_INET) {
++ slog(LOG_DEBUG, "%s: can't find ifa for %s, using defaultexternal",
++ function, inet_ntoa(destaddr));
++ close(sockfd);
++ return getdefaultexternal();
++ }
++ else {
++ memcpy((void*)&ifa, (void*)sa, sa->sa_len);
++ }
++ break;
++ }
++ if (rtm->rtm_addrs & (1<<i)) {
++ ADVANCE(cp, sa);
++ sa = (struct sockaddr *)cp;
+ }
++#undef ROUNDUP
++#undef ADVANCE
+
+- gwaddr.s_addr = destaddr.s_addr;
+- destaddr.s_addr = TOIN(sa)->sin_addr.s_addr;
+- } while (destaddr.s_addr != gwaddr.s_addr);
++ }
+
+ close(sockfd);
+
+- if (!isonexternal(sa)) {
++ if (!isonexternal(&ifa)) {
+ char a[MAXSOCKADDRSTRING];
+
+ swarnx("%s: address %s selected, but not set for external interface",
+- function, sockaddr2string(sa, a, sizeof(a)));
++ function, sockaddr2string(&ifa, a, sizeof(a)));
+
+ return getdefaultexternal();
+ }
+
+ /* LINTED pointer casts may be troublesome */
+- return TOIN(sa)->sin_addr;
++ return TOIN(&ifa)->sin_addr;
+ }
+
+ #else /* HAVE_ROUTEINFO_BSD */
+@@ -393,7 +436,7 @@
+ struct sockaddr check;
+ int match = 0;
+
+- switch ((*sockscf.external.addrv).atype) {
++ switch (sockscf.external.addrv[i].atype) {
+ case SOCKS_ADDR_IFNAME: {
+ int ifi;
+