comparison mod_proxy65/mod_proxy65.lua @ 64:853c3c7e9936

mod_proxy65: remove the proxy65 folder
author Thilo Cestonaro <thilo@cestona.ro>
date Mon, 26 Oct 2009 23:32:53 +0100
parents
children a35eb0764ac6
comparison
equal deleted inserted replaced
63:d0f5a16e7a66 64:853c3c7e9936
1 -- Copyright (C) 2009 Thilo Cestonaro
2 --
3 -- This project is MIT/X11 licensed. Please see the
4 -- COPYING file in the source package for more information.
5 --
6
7 if module:get_host_type() ~= "component" then
8 error("proxy65 should be loaded as a component, please see http://prosody.im/doc/components", 0);
9 end
10
11
12 local jid_split = require "util.jid".split;
13 local st = require "util.stanza";
14 local component_register = require "core.componentmanager".register_component;
15 local component_deregister = require "core.componentmanager".deregister_component;
16 local configmanager = require "core.configmanager";
17 local config_get = require "core.configmanager".get;
18 local connlisteners_register = require "net.connlisteners".register;
19 local connlisteners_deregister = require "net.connlisteners".deregister;
20 local adns, dns = require "net.adns", require "net.dns";
21 local add_task = require "util.timer".add_task;
22 local max_dns_depth = config.get("*", "core", "dns_max_depth") or 3;
23 local dns_timeout = config.get("*", "core", "dns_timeout") or 60;
24
25 local replies_cache = {};
26 local _host = module:get_host();
27 local _name = "SOCKS5 Bytestreams Service";
28 local _config = config_get(_host, "core", "proxy65");
29 local connlistener = {registered=false};
30 local sessions = {};
31 local component;
32
33 if _config == nil then
34 _config = {};
35 end
36 if _config.port == nil then
37 _config.port = 5000;
38 end
39
40 local function register()
41 connlistener = { default_port = _config.port; default_interface = _config.interface };
42 connlistener.registered = connlisteners_register('proxy65', connlistener);
43 if(connlistener.registered == false) then
44 error("Proxy65: Could not establish a connection listener. Check your configuration please.");
45 else
46 module:add_item("proxy65", {jid=_host, name=_name})
47 component = component_register(_host, function(origin, stanza)
48 local to_node, to_host, to_resource = jid_split(stanza.attr.to);
49 if to_node == nil then
50 local type = stanza.attr.type;
51 if type == "error" or type == "result" then return; end
52 if stanza.name == "iq" and type == "get" then
53 local xmlns = stanza.tags[1].attr.xmlns
54 if xmlns == "http://jabber.org/protocol/disco#info" then
55 origin.send(get_disco_info(stanza));
56 return true;
57 elseif xmlns == "http://jabber.org/protocol/disco#items" then
58 origin.send(get_disco_items(stanza));
59 return true;
60 elseif xmlns == "http://jabber.org/protocol/bytestreams" and stanza.tags[1].attr.sid ~= nil then
61 origin.send(get_stream_host(stanza));
62 return true;
63 end
64 end
65 end
66 return;
67 end);
68 end
69 end
70
71 local function getDefaultIP(host)
72 local handle;
73 handle = adns.lookup(function (reply)
74 handle = nil;
75
76 -- COMPAT: This is a compromise for all you CNAME-(ab)users :)
77 if not (reply and reply[#reply] and reply[#reply].a) then
78 local count = max_dns_depth;
79 reply = dns.peek(host, "CNAME", "IN");
80 while count > 0 and reply and reply[#reply] and not reply[#reply].a and reply[#reply].cname do
81 module:log("debug", "Looking up %s (DNS depth is %d)", tostring(reply[#reply].cname), count);
82 reply = dns.peek(reply[#reply].cname, "A", "IN") or dns.peek(reply[#reply].cname, "CNAME", "IN");
83 count = count - 1;
84 end
85 end
86 -- end of CNAME resolving
87
88 if reply and reply[#reply] and reply[#reply].a then
89 module:log("debug", "DNS reply for %s gives us %s", host, reply[#reply].a);
90 _config.interface = reply[#reply].a
91 return register();
92 else
93 module:log("debug", "DNS lookup failed to get a response for %s", host);
94 if host:find(".") ~= nil then
95 host = host:gsub("^[^%.]*%.", "");
96 if host:find(".") ~= nil then -- still one dot left?
97 return getDefaultIP(host);
98 end
99 end
100 error("Proxy65: Could not get an interface to bind to. Please configure one.");
101 end
102 end, host, "A", "IN");
103
104 -- Set handler for DNS timeout
105 add_task(dns_timeout, function ()
106 if handle then
107 adns.cancel(handle, true);
108 end
109 end);
110 return true;
111 end
112
113 if _config.interface ~= nil then
114 register();
115 else
116 getDefaultIP(_host); -- try to DNS lookup module:host()
117 end
118
119 function new_session(conn)
120 local w = function(s) conn.write(s:gsub("\n", "\r\n")); end;
121 local session = { conn = conn;
122 send = function (t) w(tostring(t)); end;
123 print = function (t) w("| "..tostring(t).."\n"); end;
124 disconnect = function () conn.close(); end;
125 };
126
127 return session;
128 end
129
130 function connlistener.listener(conn, data)
131 local session = sessions[conn];
132
133 if not session then
134 session = new_session(conn);
135 sessions[conn] = session;
136 end
137 if data then
138 end
139 end
140
141 function connlistener.disconnect(conn, err)
142
143 end
144
145 local function get_disco_info(stanza)
146 local reply = replies_cache.disco_info;
147 if reply == nil then
148 reply = st.iq({type='result', from=_host}):query("http://jabber.org/protocol/disco#info")
149 :tag("identity", {category='proxy', type='bytestreams', name=_name}):up()
150 :tag("feature", {var="http://jabber.org/protocol/bytestreams"});
151 replies_cache.disco_info = reply;
152 end
153
154 reply.attr.id = stanza.attr.id;
155 reply.attr.to = stanza.attr.from;
156 return reply;
157 end
158
159 local function get_disco_items(stanza)
160 local reply = replies_cache.disco_items;
161 if reply == nil then
162 reply = st.iq({type='result', from=_host}):query("http://jabber.org/protocol/disco#items");
163 replies_cache.disco_info = reply;
164 end
165
166 reply.attr.id = stanza.attr.id;
167 reply.attr.to = stanza.attr.from;
168 return reply;
169 end
170
171 local function get_stream_host(stanza)
172 local reply = replies_cache.stream_host;
173 if reply == nil then
174 reply = st.iq({type="result", from=_host})
175 :query("http://jabber.org/protocol/bytestreams")
176 :tag("streamhost", {jid=_host, host=_config.interface, port=_config.port}); -- TODO get the correct data
177 replies_cache.stream_host = reply;
178 end
179
180 reply.attr.id = stanza.attr.id;
181 reply.attr.to = stanza.attr.from;
182 reply.tags[1].attr.sid = stanza.tags[1].attr.sid;
183 return reply;
184 end
185
186 module.unload = function()
187 component_deregister(_host);
188 connlisteners_deregister("proxy65");
189 end