# HG changeset patch # User Matthew Wild # Date 1371554226 -3600 # Node ID 76e8eb9f0c1e1dd901357c5b5d17e3b88ce583fb # Parent 4a244d10a3ca190beb51f294876d68be95033c5a# Parent ea00fc524b957e68305cb5d187f7b2abe83768e4 Merge 0.9->trunk diff -r 4a244d10a3ca -r 76e8eb9f0c1e plugins/mod_s2s/s2sout.lib.lua --- a/plugins/mod_s2s/s2sout.lib.lua Sun Jun 16 15:01:31 2013 +0200 +++ b/plugins/mod_s2s/s2sout.lib.lua Tue Jun 18 12:17:06 2013 +0100 @@ -18,7 +18,7 @@ local adns = require "net.adns"; local dns = require "net.dns"; local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs; -local st = require "util.stanza"; +local local_addresses = require "util.net".local_addresses; local s2s_destroy_session = require "core.s2smanager".destroy_session; @@ -47,7 +47,6 @@ function s2sout.initiate_connection(host_session) initialize_filters(host_session); host_session.version = 1; - host_session.open_stream = session_open_stream; -- Kick the connection attempting machine into life if not s2sout.attempt_connection(host_session) then @@ -74,7 +73,7 @@ end function s2sout.attempt_connection(host_session, err) - local from_host, to_host = host_session.from_host, host_session.to_host; + local to_host = host_session.to_host; local connect_host, connect_port = to_host and idna_to_ascii(to_host), 5269; if not connect_host then @@ -267,19 +266,19 @@ function s2sout.make_connect(host_session, connect_host, connect_port) (host_session.log or log)("info", "Beginning new connection attempt to %s ([%s]:%d)", host_session.to_host, connect_host.addr, connect_port); - -- Ok, we're going to try to connect - - local from_host, to_host = host_session.from_host, host_session.to_host; - + -- Reset secure flag in case this is another -- connection attempt after a failed STARTTLS host_session.secure = nil; local conn, handler; - if connect_host.proto == "IPv4" then + local proto = connect_host.proto; + if proto == "IPv4" then conn, handler = socket.tcp(); + elseif proto == "IPv6" and socket.tcp6 then + conn, handler = socket.tcp6(); else - conn, handler = socket.tcp6(); + handler = "Unsupported protocol: "..tostring(proto); end if not conn then @@ -330,20 +329,12 @@ end for source, _ in pairs(s2s_sources) do if source == "*" or source == "0.0.0.0" then - if not socket.local_addresses then - sources[#sources + 1] = new_ip("0.0.0.0", "IPv4"); - else - for _, addr in ipairs(socket.local_addresses("ipv4", true)) do - sources[#sources + 1] = new_ip(addr, "IPv4"); - end + for _, addr in ipairs(local_addresses("ipv4", true)) do + sources[#sources + 1] = new_ip(addr, "IPv4"); end elseif source == "::" then - if not socket.local_addresses then - sources[#sources + 1] = new_ip("::", "IPv6"); - else - for _, addr in ipairs(socket.local_addresses("ipv6", true)) do - sources[#sources + 1] = new_ip(addr, "IPv6"); - end + for _, addr in ipairs(local_addresses("ipv6", true)) do + sources[#sources + 1] = new_ip(addr, "IPv6"); end else sources[#sources + 1] = new_ip(source, (source:find(":") and "IPv6") or "IPv4"); diff -r 4a244d10a3ca -r 76e8eb9f0c1e util-src/Makefile --- a/util-src/Makefile Sun Jun 16 15:01:31 2013 +0200 +++ b/util-src/Makefile Tue Jun 18 12:17:06 2013 +0100 @@ -14,9 +14,9 @@ .PHONY: all install clean .SUFFIXES: .c .o .so -all: encodings.so hashes.so pposix.so signal.so +all: encodings.so hashes.so net.so pposix.so signal.so -install: encodings.so hashes.so pposix.so signal.so +install: encodings.so hashes.so net.so pposix.so signal.so install *.so ../util/ clean: diff -r 4a244d10a3ca -r 76e8eb9f0c1e util-src/net.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util-src/net.c Tue Jun 18 12:17:06 2013 +0100 @@ -0,0 +1,107 @@ +/* Prosody IM +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- +-- Copyright (C) 2012 Paul Aurich +-- Copyright (C) 2013 Matthew Wild +-- Copyright (C) 2013 Florian Zeitz +-- +*/ + +#include +#include +#include + +#ifndef _WIN32 + #include + #include + #include + #include + #include + #include +#endif + +#include +#include + +/* Enumerate all locally configured IP addresses */ + +const char * const type_strings[] = { + "both", + "ipv4", + "ipv6", + NULL +}; + +static int lc_local_addresses(lua_State *L) +{ + /* Link-local IPv4 addresses; see RFC 3927 and RFC 5735 */ + const long ip4_linklocal = htonl(0xa9fe0000); /* 169.254.0.0 */ + const long ip4_mask = htonl(0xffff0000); +#ifndef _WIN32 + struct ifaddrs *addr = NULL, *a; + int n = 1; +#endif + int type = luaL_checkoption(L, 1, "both", type_strings); + const char link_local = lua_toboolean(L, 2); /* defaults to 0 (false) */ + const char ipv4 = (type == 0 || type == 1); + const char ipv6 = (type == 0 || type == 2); + +#ifndef _WIN32 + if (getifaddrs(&addr) < 0) { + lua_pushnil(L); + lua_pushfstring(L, "getifaddrs failed (%d): %s", errno, + strerror(errno)); + return 2; + } + + lua_newtable(L); + + for (a = addr; a; a = a->ifa_next) { + int family; + char ipaddr[INET6_ADDRSTRLEN]; + const char *tmp = NULL; + + if (a->ifa_addr == NULL || a->ifa_flags & IFF_LOOPBACK) + continue; + + family = a->ifa_addr->sa_family; + + if (ipv4 && family == AF_INET) { + struct sockaddr_in *sa = (struct sockaddr_in *)a->ifa_addr; + if (!link_local &&((sa->sin_addr.s_addr & ip4_mask) == ip4_linklocal)) + continue; + tmp = inet_ntop(family, &sa->sin_addr, ipaddr, sizeof(ipaddr)); + } else if (ipv6 && family == AF_INET6) { + struct sockaddr_in6 *sa = (struct sockaddr_in6 *)a->ifa_addr; + if (!link_local && IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr)) + continue; + if (IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr) || IN6_IS_ADDR_V4COMPAT(&sa->sin6_addr)) + continue; + tmp = inet_ntop(family, &sa->sin6_addr, ipaddr, sizeof(ipaddr)); + } + + if (tmp != NULL) { + lua_pushstring(L, tmp); + lua_rawseti(L, -2, n++); + } + /* TODO: Error reporting? */ + } + + freeifaddrs(addr); + + return 1; +#endif +} + +int luaopen_util_net(lua_State* L) +{ + luaL_Reg exports[] = { + { "local_addresses", lc_local_addresses }, + { NULL, NULL } + }; + + luaL_register(L, "net", exports); + return 1; +}