summaryrefslogtreecommitdiff
path: root/chat/ejabberd/patches
diff options
context:
space:
mode:
authormartti <martti@pkgsrc.org>2008-11-12 13:13:59 +0000
committermartti <martti@pkgsrc.org>2008-11-12 13:13:59 +0000
commita3add74345cd13f31bbf3c024f4167f98e25fe9b (patch)
treee057c67e5b5d14522e0d3f4279506ff0fa534138 /chat/ejabberd/patches
parent98ddd78a612d847d6f1248cc13591dfd6e1b50d6 (diff)
downloadpkgsrc-a3add74345cd13f31bbf3c024f4167f98e25fe9b.tar.gz
Updated chat/ejabberd to 2.0.2 (patch received from Fabrice Colliot)
* Bug fixes * Patch #389 (https://support.process-one.net/browse/EJAB-389) applied instead of the old pkgsrc patch. You MUST modify your ejabberd.cfg!
Diffstat (limited to 'chat/ejabberd/patches')
-rw-r--r--chat/ejabberd/patches/patch-aa19
-rw-r--r--chat/ejabberd/patches/patch-ac309
-rw-r--r--chat/ejabberd/patches/patch-ad221
-rw-r--r--chat/ejabberd/patches/patch-ae15
-rw-r--r--chat/ejabberd/patches/patch-af25
-rw-r--r--chat/ejabberd/patches/patch-ag218
-rw-r--r--chat/ejabberd/patches/patch-ah50
-rw-r--r--chat/ejabberd/patches/patch-ai158
8 files changed, 822 insertions, 193 deletions
diff --git a/chat/ejabberd/patches/patch-aa b/chat/ejabberd/patches/patch-aa
index 68c7e5643d8..1684638f08e 100644
--- a/chat/ejabberd/patches/patch-aa
+++ b/chat/ejabberd/patches/patch-aa
@@ -1,23 +1,26 @@
-$NetBSD: patch-aa,v 1.2 2008/04/24 08:04:13 martti Exp $
+$NetBSD: patch-aa,v 1.3 2008/11/12 13:13:59 martti Exp $
Modified for pkgsrc
---- src/Makefile.in.orig 2008-01-16 12:33:27.000000000 +0200
-+++ src/Makefile.in 2008-02-11 13:38:21.000000000 +0200
-@@ -50,13 +50,13 @@
+--- src/Makefile.in.orig 2008-08-27 12:37:52.000000000 +0300
++++ src/Makefile.in
+@@ -58,15 +58,15 @@ BEAMS = $(SOURCES:.erl=.beam)
DESTDIR =
--EJABBERDDIR = $(DESTDIR)@prefix@/var/lib/ejabberd
+-EJABBERDDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
+EJABBERDDIR = $(DESTDIR)@prefix@/lib/erlang/lib/@DISTNAME@
BEAMDIR = $(EJABBERDDIR)/ebin
+-SPOOLDIR = $(EJABBERDDIR)/db
++SPOOLDIR = @EJABBERD_VARDIR@/spool/ejabberd/db/$NODE
PRIVDIR = $(EJABBERDDIR)/priv
SODIR = $(PRIVDIR)/lib
+ PBINDIR = $(PRIVDIR)/bin
MSGSDIR = $(PRIVDIR)/msgs
--LOGDIR = $(DESTDIR)@prefix@/var/log/ejabberd
--ETCDIR = $(DESTDIR)@prefix@/etc/ejabberd
+-LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
+-ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
+LOGDIR = $(DESTDIR)/@JABBERD_LOGDIR@
+ETCDIR = $(DESTDIR)@prefix@/share/examples/ejabberd
- SBINDIR = $(DESTDIR)@prefix@/sbin
+ SBINDIR = $(DESTDIR)@sbindir@
ifeq ($(shell uname),Darwin)
diff --git a/chat/ejabberd/patches/patch-ac b/chat/ejabberd/patches/patch-ac
index cb6a3937cdf..b650077f6b4 100644
--- a/chat/ejabberd/patches/patch-ac
+++ b/chat/ejabberd/patches/patch-ac
@@ -1,51 +1,272 @@
-$NetBSD: patch-ac,v 1.1.1.1 2008/03/10 08:58:32 martti Exp $
+$NetBSD: patch-ac,v 1.2 2008/11/12 13:13:59 martti Exp $
-Patch from Fabrice Colliot: support for multiple listeners on same port
-number (eg IPv4 and IPv6 simultaneously).
+Modified to use IPv6/v4 patch (https://support.process-one.net/browse/EJAB-389)
---- src/ejabberd.cfg.example.orig 2008-01-16 12:33:27.000000000 +0200
-+++ src/ejabberd.cfg.example 2008-02-14 15:25:12.000000000 +0200
-@@ -106,7 +106,7 @@
- {listen,
- [
+--- doc/guide.tex.orig 2008-08-27 12:37:52.000000000 +0300
++++ doc/guide.tex
+@@ -713,34 +713,80 @@ The option \option{listen} defines for w
+ will listen and what services will be run on them. Each element of the list is a
+ tuple with the following elements:
+ \begin{itemize}
+-\item Port number.
+-\item Module that serves this port.
+-\item Options to this module.
++\item Port number. Optionally also the IP address.
++\item Listening module that serves this port.
++\item Options for the TCP socket and for the listening module.
+ \end{itemize}
+
++With the basic syntax the ports will listen on all IPv4 network addresses:
++\begin{verbatim}
++{listen, [
++ {<port-number>, <module>, [<options>]},
++ {<port-number>, <module>, [<options>]},
++ ...
++ {<port-number>, <module>, [<options>]}
++ ]}.
++\end{verbatim}
++
++It is possible to specify the IP address for a port using the full syntax:
++\begin{verbatim}
++ {{<port-number>, <ip-address>}, <module>, [<options>]}
++\end{verbatim}
++
++
++\makesubsubsection{listened-port}{Port Number and IP Address}
++
++The port number defines which port to listen for incoming connections.
++It can be a Jabber/XMPP standard port
++(see section \ref{firewall}) or any other valid port number.
++
++The IP address can be represented with a string
++or an Erlang tuple with decimal or hexadecimal numbers.
++The socket will listen only in that network interface.
++It is possible to specify a generic address,
++so \ejabberd{} will listen in all addresses.
++Depending in the type of the IP address, IPv4 or IPv6 will be used.
++
++Some example values for IP address:
++\begin{itemize}
++\item \verb|"0.0.0.0"| to listen in all IPv4 network interfaces. This is the default value when no IP is specified.
++\item \verb|"::"| to listen in all IPv6 network interfaces
++\item \verb|"10.11.12.13"| is the IPv4 address \verb|10.11.12.13|
++\item \verb|"::FFFF:127.0.0.1"| is the IPv6 address \verb|::FFFF:127.0.0.1/128|
++\item \verb|{10, 11, 12, 13}| is the IPv4 address \verb|10.11.12.13|
++\item \verb|{0, 0, 0, 0, 0, 65535, 32512, 1}| is the IPv6 address \verb|::FFFF:127.0.0.1/128|
++\item \verb|{16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1}| is the IPv6 address \verb|FDCA:8AB6:A243:75EF::1/128|
++\end{itemize}
++
++
++\makesubsubsection{listened-module}{Listening Module}
++
+ \ind{modules!ejabberd\_c2s}\ind{modules!ejabberd\_s2s\_in}\ind{modules!ejabberd\_service}\ind{modules!ejabberd\_http}\ind{protocols!XEP-0114: Jabber Component Protocol}
+ The available modules, their purpose and the options allowed by each one are:
+ \begin{description}
+ \titem{\texttt{ejabberd\_c2s}}
+ Handles c2s connections.\\
+- Options: \texttt{access}, \texttt{certfile}, \texttt{inet6},
+- \texttt{ip}, \texttt{max\_stanza\_size}, \texttt{shaper},
++ Options: \texttt{access}, \texttt{certfile},
++ \texttt{max\_stanza\_size}, \texttt{shaper},
+ \texttt{starttls}, \texttt{starttls\_required}, \texttt{tls},
+ \texttt{zlib}
+ \titem{\texttt{ejabberd\_s2s\_in}}
+ Handles incoming s2s connections.\\
+- Options: \texttt{inet6}, \texttt{ip}, \texttt{max\_stanza\_size}
++ Options: \texttt{max\_stanza\_size}
+ \titem{\texttt{ejabberd\_service}}
+ Interacts with \footahref{http://www.ejabberd.im/tutorials-transports}{external components}
+ (as defined in the Jabber Component Protocol (\xepref{0114}).\\
+- Options: \texttt{access}, \texttt{hosts}, \texttt{inet6},
+- \texttt{ip}, \texttt{shaper}, \texttt{service\_check\_from}
++ Options: \texttt{access}, \texttt{hosts},
++ \texttt{shaper}, \texttt{service\_check\_from}
+ \titem{\texttt{ejabberd\_http}}
+ Handles incoming HTTP connections.\\
+ Options: \texttt{certfile}, \texttt{http\_bind}, \texttt{http\_poll},
+- \texttt{inet6}, \texttt{ip}, \texttt{request\_handlers}, \texttt{tls}, \texttt{web\_admin}\\
++ \texttt{request\_handlers}, \texttt{tls}, \texttt{web\_admin}\\
+ \end{description}
-- {5222, ejabberd_c2s, [
-+ {1, 5222, ejabberd_c2s, [
++
++\makesubsubsection{listened-options}{Options}
++
+ This is a detailed description of each option allowed by the listening modules:
+ \begin{description}
+ \titem{\{access, <access rule>\}} \ind{options!access}This option defines
+@@ -785,13 +831,7 @@ This is a detailed description of each o
+ is also needed in the \Jabber{} client. Remark also that HTTP Polling can be
+ interesting to host a web-based \Jabber{} client such as
+ \footahref{http://jwchat.sourceforge.net/}{JWChat}.
+- \titem{inet6} \ind{options!inet6}\ind{IPv6}Set up the socket for IPv6 instead of IPv4.
+- Note: this option is not required for S2S outgoing connections,
+- because when ejabberd attempts to establish a S2S outgoing connection
+- it first tries IPv4, and if that fails it attempts with IPv6.
+- \titem{\{ip, IPAddress\}} \ind{options!ip}This option specifies which network
+- interface to listen for. For example \verb|{ip, {192, 168, 1, 1}}|.
+- \titem{\{max\_stanza\_size, Size\}}
++ \titem{\{max\_stanza\_size, Size\}}
+ \ind{options!max\_stanza\_size}This option specifies an
+ approximate maximum size in bytes of XML stanzas. Approximate,
+ because it is calculated with the precision of one block of readed
+@@ -838,7 +878,7 @@ This is a detailed description of each o
+ option will not affect connections (there will be no stream compression).
+ \end{description}
- %%
- %% If TLS is compiled and you installed a SSL
-@@ -123,14 +123,14 @@
- %%
- %% To enable the old SSL connection method in port 5223:
- %%
-- %%{5223, ejabberd_c2s, [
-+ %%{2, 5223, ejabberd_c2s, [
- %% {access, c2s},
- %% {shaper, c2s_shaper},
- %% {certfile, "/path/to/ssl.pem"}, tls,
- %% {max_stanza_size, 65536}
- %% ]},
+-There are some additional global options:
++There are some additional global options that can be specified in the ejabberd configuration file (outside \term{listen}):
+ \begin{description}
+ \titem{\{s2s\_use\_starttls, true|false\}}
+ \ind{options!s2s\_use\_starttls}\ind{STARTTLS}This option defines whether to
+@@ -859,6 +899,8 @@ There are some additional global options
+ Specified in seconds. The default value is 300 seconds (5 minutes).
+ \end{description}
++\makesubsubsection{listened-examples}{Examples}
++
+ For example, the following simple configuration defines:
+ \begin{itemize}
+ \item There are three domains. The default certificate file is \term{server.pem}.
+@@ -866,17 +908,17 @@ However, the c2s and s2s connections to
+ \item Port 5222 listens for c2s connections with STARTTLS,
+ and also allows plain connections for old clients.
+ \item Port 5223 listens for c2s connections with the old SSL.
+-\item Port 5269 listens for s2s connections with STARTTLS.
++\item Port 5269 listens for s2s connections with STARTTLS. The socket is set for IPv6 instead of IPv4.
+ \item Port 5280 listens for HTTP requests, and serves the HTTP Poll service.
+ \item Port 5281 listens for HTTP requests, and serves the Web Admin using HTTPS as explained in
+- section~\ref{webadmin}.
++ section~\ref{webadmin}. The socket only listens connections to the IP address 127.0.0.1.
+ \end{itemize}
+ \begin{verbatim}
+ {hosts, ["example.com", "example.org", "example.net"]}.
+ {listen,
+ [
+ {5222, ejabberd_c2s, [
+- {access, c2s},
++ {access, c2s},
+ {shaper, c2s_shaper},
+ starttls, {certfile, "/etc/ejabberd/server.pem"},
+ {max_stanza_size, 65536}
+@@ -887,17 +929,17 @@ However, the c2s and s2s connections to
+ tls, {certfile, "/etc/ejabberd/server.pem"},
+ {max_stanza_size, 65536}
+ ]},
- {5269, ejabberd_s2s_in, [
-+ {3, 5269, ejabberd_s2s_in, [
- {shaper, s2s_shaper},
- {max_stanza_size, 131072}
- ]},
-@@ -138,7 +138,7 @@
- %%
- %% ejabberd_service: Interact with external components (transports...)
- %%
-- %%{8888, ejabberd_service, [
-+ %%{4, 8888, ejabberd_service, [
- %% {access, all},
- %% {shaper_rule, fast},
- %% {ip, {127, 0, 0, 1}},
-@@ -147,7 +147,7 @@
- %% }
- %% ]},
+- {shaper, s2s_shaper},
+- {max_stanza_size, 131072}
+- ]},
++ {{5269, "::"}, ejabberd_s2s_in, [
++ {shaper, s2s_shaper},
++ {max_stanza_size, 131072}
++ ]},
+ {5280, ejabberd_http, [
+ http_poll
+ ]},
+- {5281, ejabberd_http, [
+- web_admin,
+- tls, {certfile, "/etc/ejabberd/server.pem"},
+- ]}
++ {{5281, "127.0.0.1"}, ejabberd_http, [
++ web_admin,
++ tls, {certfile, "/etc/ejabberd/server.pem"},
++ ]}
+ ]
+ }.
+ {s2s_use_starttls, true}.
+@@ -907,21 +949,23 @@ However, the c2s and s2s connections to
-- {5280, ejabberd_http, [
-+ {5, 5280, ejabberd_http, [
- http_poll,
- web_admin
- ]}
+ In this example, the following configuration defines that:
+ \begin{itemize}
+-\item c2s connections are listened for on port 5222 and 5223 (SSL) and denied
++\item c2s connections are listened for on port 5222 (all IPv4 addresses) and
++ on port 5223 (SSL, IP 192.168.0.1 and fdca:8ab6:a243:75ef::1) and denied
+ for the user called `\term{bad}'.
+-\item s2s connections are listened for on port 5269 with STARTTLS for secured
+- traffic enabled.
++\item s2s connections are listened for on port 5269 (all IPv4 addresses)
++ with STARTTLS for secured traffic enabled.
+ Incoming and outgoing connections of remote Jabber servers are denied,
+ only two servers can connect: "jabber.example.org" and "example.com".
+-\item Port 5280 is serving the Web Admin and the HTTP Polling service. Note
++\item Port 5280 is serving the Web Admin and the HTTP Polling service
++ in all the IPv4 addresses. Note
+ that it is also possible to serve them on different ports. The second
+ example in section~\ref{webadmin} shows how exactly this can be done.
+ \item All users except for the administrators have a traffic of limit
+ 1,000\,Bytes/second
+ \item \ind{transports!AIM}The
+ \footahref{http://www.ejabberd.im/pyaimt}{AIM transport}
+- \jid{aim.example.org} is connected to port 5233 with password
+- `\term{aimsecret}'.
++ \jid{aim.example.org} is connected to port 5233 on localhost IP addresses
++ (127.0.0.1 and ::1) with password `\term{aimsecret}'.
+ \item \ind{transports!ICQ}The ICQ transport JIT (\jid{icq.example.org} and
+ \jid{sms.example.org}) is connected to port 5234 with password
+ `\term{jitsecret}'.
+@@ -949,13 +993,32 @@ In this example, the following configura
+ {access, c2s_shaper, [{none, admin},
+ {normal, all}]}.
+ {listen,
+- [{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]},
+- {5223, ejabberd_c2s, [{access, c2s},
+- ssl, {certfile, "/path/to/ssl.pem"}]},
+- {5269, ejabberd_s2s_in, []},
+- {5280, ejabberd_http, [http_poll, web_admin]},
+- {5233, ejabberd_service, [{hosts, ["aim.example.org"],
+- [{password, "aimsecret"}]}]},
++ [{5222, ejabberd_c2s, [
++ {access, c2s},
++ {shaper, c2s_shaper}
++ ]},
++ {{5223, {192, 168, 0, 1}}, ejabberd_c2s, [
++ {access, c2s},
++ ssl, {certfile, "/path/to/ssl.pem"}
++ ]},
++ {{5223, {16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1}},
++ ejabberd_c2s, [
++ {access, c2s},
++ ssl, {certfile, "/path/to/ssl.pem"}
++ ]},
++ {5269, ejabberd_s2s_in, []},
++ {{5280, {0, 0, 0, 0}}, ejabberd_http, [
++ http_poll,
++ web_admin
++ ]},
++ {{5233, {127, 0, 0, 1}}, ejabberd_service, [
++ {hosts, ["aim.example.org"],
++ [{password, "aimsecret"}]}
++ ]},
++ {{5233, "::1"}, ejabberd_service, [
++ {hosts, ["aim.example.org"],
++ [{password, "aimsecret"}]}
++ ]},
+ {5234, ejabberd_service, [{hosts, ["icq.example.org", "sms.example.org"],
+ [{password, "jitsecret"}]}]},
+ {5235, ejabberd_service, [{hosts, ["msn.example.org"],
+@@ -3672,7 +3735,7 @@ Examples:
+ \item For security reasons, you can serve the Web Admin on a secured
+ connection, on a port differing from the HTTP Polling interface, and bind it
+ to the internal LAN IP. The Web Admin will be accessible by pointing your
+- web browser to \verb|https://192.168.1.1:5280/admin/|:
++ web browser to \verb|https://192.168.1.1:5282/admin/|:
+ \begin{verbatim}
+
+ {hosts, ["example.org"]}.
+@@ -3680,9 +3743,13 @@ Examples:
+ {listen,
+ [
+ ...
+- {5270, ejabberd_http, [http_poll]},
+- {5280, ejabberd_http, [web_admin, {ip, {192, 168, 1, 1}},
+- tls, {certfile, "/usr/local/etc/server.pem"}]},
++ {5280, ejabberd_http, [
++ http_poll
++ ]},
++ {{5282, "192.168.1.1"}, ejabberd_http, [
++ web_admin,
++ tls, {certfile, "/usr/local/etc/server.pem"}
++ ]},
+ ...
+ ]}.
+ \end{verbatim}
diff --git a/chat/ejabberd/patches/patch-ad b/chat/ejabberd/patches/patch-ad
index f8a85a71ec0..86ca71bf880 100644
--- a/chat/ejabberd/patches/patch-ad
+++ b/chat/ejabberd/patches/patch-ad
@@ -1,140 +1,93 @@
-$NetBSD: patch-ad,v 1.1.1.1 2008/03/10 08:58:32 martti Exp $
+$NetBSD: patch-ad,v 1.2 2008/11/12 13:13:59 martti Exp $
-Patch from Fabrice Colliot: support for multiple listeners on same port
-number (eg IPv4 and IPv6 simultaneously).
+Modified to use IPv6/v4 patch (https://support.process-one.net/browse/EJAB-389)
---- src/ejabberd_listener.erl.orig 2008-01-16 12:33:27.000000000 +0200
-+++ src/ejabberd_listener.erl 2008-02-14 15:25:12.000000000 +0200
-@@ -27,12 +27,12 @@
- -module(ejabberd_listener).
- -author('alexey@process-one.net').
+--- src/ejabberd.cfg.example.orig 2008-11-12 15:15:04.000000000 +0200
++++ src/ejabberd.cfg.example
+@@ -107,10 +107,9 @@
+ [
---export([start_link/0, init/1, start/3,
-- init/3,
-- init_ssl/4,
-- start_listener/3,
-+-export([start_link/0, init/1, start/4,
-+ init/4,
-+ init_ssl/5,
-+ start_listener/4,
- stop_listener/1,
-- add_listener/3,
-+ add_listener/4,
- delete_listener/1
- ]).
+ {5222, ejabberd_c2s, [
+-
+ %%
+ %% If TLS is compiled and you installed a SSL
+- %% certificate, put the correct path to the
++ %% certificate, put the correct path to the
+ %% file and uncomment this line:
+ %%
+ %%{certfile, "/path/to/ssl.pem"}, starttls,
+@@ -123,12 +122,12 @@
+ %%
+ %% To enable the old SSL connection method in port 5223:
+ %%
+- %%{5223, ejabberd_c2s, [
+- %% {access, c2s},
+- %% {shaper, c2s_shaper},
+- %% {certfile, "/path/to/ssl.pem"}, tls,
+- %% {max_stanza_size, 65536}
+- %% ]},
++ {5223, ejabberd_c2s, [
++ {access, c2s},
++ {shaper, c2s_shaper},
++ {certfile, "/path/to/ssl.pem"}, tls,
++ {max_stanza_size, 65536}
++ ]},
-@@ -49,9 +49,9 @@
- Ls ->
- {ok, {{one_for_one, 10, 1},
- lists:map(
-- fun({Port, Module, Opts}) ->
-- {Port,
-- {?MODULE, start, [Port, Module, Opts]},
-+ fun({ListenerID, Port, Module, Opts}) ->
-+ {ListenerID,
-+ {?MODULE, start, [ListenerID, Port, Module, Opts]},
- transient,
- brutal_kill,
- worker,
-@@ -60,7 +60,7 @@
- end.
+ {5269, ejabberd_s2s_in, [
+ {shaper, s2s_shaper},
+@@ -138,14 +137,14 @@
+ %%
+ %% ejabberd_service: Interact with external components (transports...)
+ %%
+- %%{8888, ejabberd_service, [
+- %% {access, all},
+- %% {shaper_rule, fast},
+- %% {ip, {127, 0, 0, 1}},
+- %% {hosts, ["icq.example.org", "sms.example.org"],
+- %% [{password, "secret"}]
+- %% }
+- %% ]},
++ %%{{8888, "127.0.0.1"},
++ %% ejabberd_service, [
++ %% {access, all},
++ %% {shaper_rule, fast},
++ %% {hosts, ["icq.example.org", "sms.example.org"],
++ %% [{password, "secret"}]
++ %% }
++ %% ]},
+ {5280, ejabberd_http, [
+ http_poll,
+@@ -224,17 +223,26 @@
+ %% List of LDAP servers:
+ %%{ldap_servers, ["localhost"]}.
+ %%
+-%% LDAP attribute that holds user ID:
+-%%{ldap_uids, [{"mail", "%u@mail.example.org"}]}.
++%% Encryption of connection to LDAP servers:
++%%{ldap_encrypt, tls}.
+ %%
+-%% Search base of LDAP directory:
+-%%{ldap_base, "dc=example,dc=com"}.
++%% Port connect to LDAP server:
++%%{ldap_port, 636}.
+ %%
+ %% LDAP manager:
+-%%{ldap_rootdn, "dc=example,dc=com"}.
++%%{ldap_rootdn, "dc=example,dc=com"}.
+ %%
+ %% Password to LDAP manager:
+-%%{ldap_password, "******"}.
++%%{ldap_password, "******"}.
++%%
++%% Search base of LDAP directory:
++%%{ldap_base, "dc=example,dc=com"}.
++%%
++%% LDAP attribute that holds user ID:
++%%{ldap_uids, [{"mail", "%u@mail.example.org"}]}.
++%%
++%% LDAP filter:
++%%{ldap_filter, "(objectClass=shadowAccount)"}.
--start(Port, Module, Opts) ->
-+start(ListenerID, Port, Module, Opts) ->
- SSLError = "There is a problem with your ejabberd configuration file: the option 'ssl' for listening sockets is no longer available. To get SSL encryption use the option 'tls'.",
- case lists:keysearch(ssl, 1, Opts) of
- {value, {ssl, _SSLOpts}} ->
-@@ -77,11 +77,11 @@
- {error, SSLError};
- false ->
- {ok, proc_lib:spawn_link(?MODULE, init,
-- [Port, Module, Opts])}
-+ [ListenerID, Port, Module, Opts])}
- end
- end.
-
--init(Port, Module, Opts) ->
-+init(ListenerID, Port, Module, Opts) ->
- SockOpts = lists:filter(fun({ip, _}) -> true;
- (inet6) -> true;
- (inet) -> true;
-@@ -100,7 +100,7 @@
- accept(ListenSocket, Module, Opts);
- {error, Reason} ->
- ?ERROR_MSG("Failed to open socket for ~p: ~p",
-- [{Port, Module, Opts}, Reason]),
-+ [{ListenerID, Port, Module, Opts}, Reason]),
- error
- end.
-
-@@ -128,7 +128,7 @@
- end.
-
-
--init_ssl(Port, Module, Opts, SSLOpts) ->
-+init_ssl(ListenerID, Port, Module, Opts, SSLOpts) ->
- SockOpts = lists:filter(fun({ip, _}) -> true;
- (inet6) -> true;
- (inet) -> true;
-@@ -151,7 +151,7 @@
- accept_ssl(ListenSocket, Module, Opts);
- {error, Reason} ->
- ?ERROR_MSG("Failed to open socket for ~p: ~p",
-- [{Port, Module, Opts}, Reason]),
-+ [{ListenerID, Port, Module, Opts}, Reason]),
- error
- end.
-
-@@ -178,8 +178,8 @@
- end.
-
-
--start_listener(Port, Module, Opts) ->
-- ChildSpec = {Port,
-+start_listener(ListenerID, Port, Module, Opts) ->
-+ ChildSpec = {ListenerID,
- {?MODULE, start, [Port, Module, Opts]},
- transient,
- brutal_kill,
-@@ -187,30 +187,30 @@
- [?MODULE]},
- supervisor:start_child(ejabberd_listeners, ChildSpec).
-
--stop_listener(Port) ->
-- supervisor:terminate_child(ejabberd_listeners, Port),
-- supervisor:delete_child(ejabberd_listeners, Port).
-+stop_listener(ListenerID) ->
-+ supervisor:terminate_child(ejabberd_listeners, ListenerID),
-+ supervisor:delete_child(ejabberd_listeners, ListenerID).
-
--add_listener(Port, Module, Opts) ->
-+add_listener(ListenerID, Port, Module, Opts) ->
- Ports = case ejabberd_config:get_local_option(listen) of
- undefined ->
- [];
- Ls ->
- Ls
- end,
-- Ports1 = lists:keydelete(Port, 1, Ports),
-- Ports2 = [{Port, Module, Opts} | Ports1],
-+ Ports1 = lists:keydelete(ListenerID, 1, Ports),
-+ Ports2 = [{ListenerID, Port, Module, Opts} | Ports1],
- ejabberd_config:add_local_option(listen, Ports2),
-- start_listener(Port, Module, Opts).
-+ start_listener(ListenerID, Port, Module, Opts).
-
--delete_listener(Port) ->
-+delete_listener(ListenerID) ->
- Ports = case ejabberd_config:get_local_option(listen) of
- undefined ->
- [];
- Ls ->
- Ls
- end,
-- Ports1 = lists:keydelete(Port, 1, Ports),
-+ Ports1 = lists:keydelete(ListenerID, 1, Ports),
- ejabberd_config:add_local_option(listen, Ports1),
-- stop_listener(Port).
-+ stop_listener(ListenerID).
-
+ %%
+ %% Anonymous login support:
diff --git a/chat/ejabberd/patches/patch-ae b/chat/ejabberd/patches/patch-ae
index ad36665ab06..aa65b1561cc 100644
--- a/chat/ejabberd/patches/patch-ae
+++ b/chat/ejabberd/patches/patch-ae
@@ -1,11 +1,11 @@
-$NetBSD: patch-ae,v 1.2 2008/04/22 11:31:05 martti Exp $
+$NetBSD: patch-ae,v 1.3 2008/11/12 13:13:59 martti Exp $
-Keep things tidy (nothing under /usr/pkg/var)
+Modified for pkgsrc
---- src/ejabberdctl.template.orig 2008-02-22 16:42:12.000000000 +0200
-+++ src/ejabberdctl.template 2008-02-22 17:45:01.000000000 +0200
-@@ -13,8 +13,8 @@
- ERLANG_NODE=$NODE@$HOST
+--- src/ejabberdctl.template.orig 2008-08-27 12:37:52.000000000 +0300
++++ src/ejabberdctl.template
+@@ -14,8 +14,8 @@ ERLANG_NODE=$NODE@$HOST
+ ERL=@erl@
ROOTDIR=@rootdir@
EJABBERD_CONFIG_PATH=$ROOTDIR/etc/ejabberd/ejabberd.cfg
-LOGS_DIR=$ROOTDIR/var/log/ejabberd/
@@ -15,7 +15,7 @@ Keep things tidy (nothing under /usr/pkg/var)
# read custom configuration
CONFIG=$ROOTDIR/etc/ejabberd/ejabberdctl.cfg
-@@ -42,15 +42,15 @@
+@@ -43,16 +43,16 @@ NAME=-name
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES"
# define additional environment variables
@@ -25,6 +25,7 @@ Keep things tidy (nothing under /usr/pkg/var)
+EJABBERD_EBIN=$ROOTDIR/lib/erlang/lib/@DISTNAME@/ebin
+EJABBERD_MSGS_PATH=$ROOTDIR/lib/erlang/lib/@DISTNAME@/priv/msgs
+EJABBERD_SO_PATH=$ROOTDIR/lib/erlang/lib/@DISTNAME@/priv/lib
+ EJABBERD_BIN_PATH=$ROOTDIR/var/lib/ejabberd/priv/bin
EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
SASL_LOG_PATH=$LOGS_DIR/sasl.log
DATETIME=`date "+%Y%m%d-%H%M%S"`
diff --git a/chat/ejabberd/patches/patch-af b/chat/ejabberd/patches/patch-af
new file mode 100644
index 00000000000..ed0c27e215e
--- /dev/null
+++ b/chat/ejabberd/patches/patch-af
@@ -0,0 +1,25 @@
+$NetBSD: patch-af,v 1.1 2008/11/12 13:13:59 martti Exp $
+
+Modified to use IPv6/v4 patch (https://support.process-one.net/browse/EJAB-389)
+
+--- src/ejabberd_config.erl.orig 2008-08-27 12:37:52.000000000 +0300
++++ src/ejabberd_config.erl
+@@ -140,8 +140,16 @@ process_term(Term, State) ->
+ {host_config, Host, Terms} ->
+ lists:foldl(fun(T, S) -> process_host_term(T, Host, S) end,
+ State, Terms);
+- {listen, Val} ->
+- add_option(listen, Val, State);
++ {listen, Listeners} ->
++ Listeners2 =
++ lists:map(
++ fun({PortIP, Module, Opts}) ->
++ {Port, IPT, _, _, OptsClean} =
++ ejabberd_listener:parse_listener_portip(PortIP, Opts),
++ {{Port, IPT}, Module, OptsClean}
++ end,
++ Listeners),
++ add_option(listen, Listeners2, State);
+ {language, Val} ->
+ add_option(language, Val, State);
+ {outgoing_s2s_port, Port} ->
diff --git a/chat/ejabberd/patches/patch-ag b/chat/ejabberd/patches/patch-ag
new file mode 100644
index 00000000000..f07f97aaabe
--- /dev/null
+++ b/chat/ejabberd/patches/patch-ag
@@ -0,0 +1,218 @@
+$NetBSD: patch-ag,v 1.1 2008/11/12 13:13:59 martti Exp $
+
+Modified to use IPv6/v4 patch (https://support.process-one.net/browse/EJAB-389)
+
+--- src/ejabberd_listener.erl.orig 2008-08-27 12:37:52.000000000 +0300
++++ src/ejabberd_listener.erl
+@@ -32,6 +32,7 @@
+ init_ssl/4,
+ start_listener/3,
+ stop_listener/1,
++ parse_listener_portip/2,
+ add_listener/3,
+ delete_listener/1
+ ]).
+@@ -47,8 +48,7 @@ init(_) ->
+ undefined ->
+ ignore;
+ Ls ->
+- {ok, {{one_for_one, 10, 1},
+- lists:map(
++ Ls2 = lists:map(
+ fun({Port, Module, Opts}) ->
+ {Port,
+ {?MODULE, start, [Port, Module, Opts]},
+@@ -56,7 +56,20 @@ init(_) ->
+ brutal_kill,
+ worker,
+ [?MODULE]}
+- end, Ls)}}
++ end, Ls),
++ report_duplicated_portips(Ls),
++ {ok, {{one_for_one, 10, 1}, Ls2}}
++ end.
++
++report_duplicated_portips(L) ->
++ LKeys = [Port || {Port, _, _} <- L],
++ LNoDupsKeys = proplists:get_keys(L),
++ case LKeys -- LNoDupsKeys of
++ [] -> ok;
++ Dups ->
++ ?CRITICAL_MSG("In the ejabberd configuration there are duplicated "
++ "Port number + IP address:~n ~p",
++ [Dups])
+ end.
+
+
+@@ -81,13 +94,16 @@ start(Port, Module, Opts) ->
+ end
+ end.
+
+-init(Port, Module, Opts) ->
++init(PortIP, Module, Opts1) ->
++ {Port, IPT, IPS, IPV, OptsClean} = parse_listener_portip(PortIP, Opts1),
++ %% The first inet|inet6 and the last {ip, _} work,
++ %% so overriding those in Opts
++ Opts = [IPV | OptsClean] ++ [{ip, IPT}],
+ SockOpts = lists:filter(fun({ip, _}) -> true;
+ (inet6) -> true;
+ (inet) -> true;
+ (_) -> false
+ end, Opts),
+-
+ Res = gen_tcp:listen(Port, [binary,
+ {packet, 0},
+ {active, false},
+@@ -99,11 +115,77 @@ init(Port, Module, Opts) ->
+ {ok, ListenSocket} ->
+ accept(ListenSocket, Module, Opts);
+ {error, Reason} ->
+- ?ERROR_MSG("Failed to open socket for ~p: ~p",
+- [{Port, Module, Opts}, Reason]),
+- error
++ ReasonT = case Reason of
++ eaddrnotavail -> "IP address not available: " ++ IPS;
++ _ -> atom_to_list(Reason)
++ end,
++ ?ERROR_MSG("Failed to open socket:~n ~p~nReason: ~s",
++ [{Port, Module, SockOpts}, ReasonT]),
++ {error, ReasonT}
++ end.
++
++%% @spec (PortIP, Opts) -> {Port, IPT, IPS, IPV, OptsClean}
++%% where
++%% PortIP = Port | {Port, IPT | IPS}
++%% Port = integer()
++%% IPT = tuple()
++%% IPS = string()
++%% IPV = inet | inet6
++%% Opts = [IPV | {ip, IPT} | atom() | tuple()]
++%% OptsClean = [atom() | tuple()]
++%% @doc Parse any kind of ejabberd listener specification.
++%% The parsed options are returned in several formats.
++%% OptsClean does not include inet/inet6 or ip options.
++%% Opts can include the options inet6 and {ip, Tuple},
++%% but they are only used when no IP address was specified in the PortIP.
++%% The IP version (either IPv4 or IPv6) is inferred from the IP address type,
++%% so the option inet/inet6 is only used when no IP is specified at all.
++parse_listener_portip(PortIP, Opts) ->
++ {IPOpt, Opts2} = strip_ip_option(Opts),
++ {IPVOpt, OptsClean} = case lists:member(inet6, Opts2) of
++ true -> {inet6, Opts2 -- [inet6]};
++ false -> {inet, Opts2}
++ end,
++ {Port, IPT, IPS} = case PortIP of
++ P when is_integer(P) ->
++ T = get_ip_tuple(IPOpt, IPVOpt),
++ S = inet_parse:ntoa(T),
++ {P, T, S};
++ {P, T} when is_integer(P) and is_tuple(T) ->
++ S = inet_parse:ntoa(T),
++ {P, T, S};
++ {P, S} when is_integer(P) and is_list(S) ->
++ [S | _] = string:tokens(S, "/"),
++ {ok, T} = inet_parse:address(S),
++ {P, T, S}
++ end,
++ IPV = case size(IPT) of
++ 4 -> inet;
++ 8 -> inet6
++ end,
++ {Port, IPT, IPS, IPV, OptsClean}.
++
++strip_ip_option(Opts) ->
++ {IPL, OptsNoIP} = lists:partition(
++ fun({ip, _}) -> true;
++ (_) -> false
++ end,
++ Opts),
++ case IPL of
++ %% Only the first ip option is considered
++ [{ip, T1} | _] when is_tuple(T1) ->
++ {T1, OptsNoIP};
++ [] ->
++ {no_ip_option, OptsNoIP}
+ end.
+
++get_ip_tuple(no_ip_option, inet) ->
++ {0, 0, 0, 0};
++get_ip_tuple(no_ip_option, inet6) ->
++ {0, 0, 0, 0, 0, 0, 0, 0};
++get_ip_tuple(IPOpt, _IPVOpt) ->
++ IPOpt.
++
+ accept(ListenSocket, Module, Opts) ->
+ case gen_tcp:accept(ListenSocket) of
+ {ok, Socket} ->
+@@ -178,6 +260,7 @@ accept_ssl(ListenSocket, Module, Opts) -
+ end.
+
+
++%% @spec (Port, Module, Opts) -> {ok, Pid} | {error, Error}
+ start_listener(Port, Module, Opts) ->
+ ChildSpec = {Port,
+ {?MODULE, start, [Port, Module, Opts]},
+@@ -191,26 +274,49 @@ stop_listener(Port) ->
+ supervisor:terminate_child(ejabberd_listeners, Port),
+ supervisor:delete_child(ejabberd_listeners, Port).
+
+-add_listener(Port, Module, Opts) ->
+- Ports = case ejabberd_config:get_local_option(listen) of
+- undefined ->
+- [];
+- Ls ->
+- Ls
+- end,
+- Ports1 = lists:keydelete(Port, 1, Ports),
+- Ports2 = [{Port, Module, Opts} | Ports1],
+- ejabberd_config:add_local_option(listen, Ports2),
+- start_listener(Port, Module, Opts).
++%% @spec (PortIP, Module, Opts) -> {ok, Pid} | {error, Error}
++%% where
++%% PortIP = {Port, IPT | IPS}
++%% Port = integer()
++%% IPT = tuple()
++%% IPS = string()
++%% IPV = inet | inet6
++%% Module = atom()
++%% Opts = [IPV | {ip, IPT} | atom() | tuple()]
++%% @doc Add a listener and store in config if success
++add_listener(PortIP, Module, Opts) ->
++ case start_listener(PortIP, Module, Opts) of
++ {ok, _Pid} ->
++ Ports = case ejabberd_config:get_local_option(listen) of
++ undefined ->
++ [];
++ Ls ->
++ Ls
++ end,
++ Ports1 = lists:keydelete(PortIP, 1, Ports),
++ Ports2 = [{PortIP, Module, Opts} | Ports1],
++ ejabberd_config:add_local_option(listen, Ports2),
++ ok;
++ {error, {already_started, _Pid}} ->
++ {error, {already_started, PortIP}};
++ {error, Error} ->
++ {error, Error}
++ end.
+
+-delete_listener(Port) ->
++%% @spec (PortIP) -> ok
++%% where
++%% PortIP = {Port, IPT | IPS}
++%% Port = integer()
++%% IPT = tuple()
++%% IPS = string()
++delete_listener(PortIP) ->
+ Ports = case ejabberd_config:get_local_option(listen) of
+ undefined ->
+ [];
+ Ls ->
+ Ls
+ end,
+- Ports1 = lists:keydelete(Port, 1, Ports),
++ Ports1 = lists:keydelete(PortIP, 1, Ports),
+ ejabberd_config:add_local_option(listen, Ports1),
+- stop_listener(Port).
++ stop_listener(PortIP).
+
diff --git a/chat/ejabberd/patches/patch-ah b/chat/ejabberd/patches/patch-ah
new file mode 100644
index 00000000000..0c65d98a116
--- /dev/null
+++ b/chat/ejabberd/patches/patch-ah
@@ -0,0 +1,50 @@
+$NetBSD: patch-ah,v 1.1 2008/11/12 13:13:59 martti Exp $
+
+Modified to use IPv6/v4 patch (https://support.process-one.net/browse/EJAB-389)
+
+--- src/mod_proxy65/mod_proxy65_service.erl.orig 2008-08-27 12:37:52.000000000 +0300
++++ src/mod_proxy65/mod_proxy65_service.erl
+@@ -52,6 +52,7 @@
+ name,
+ stream_addr,
+ port,
++ ip,
+ acl
+ }).
+
+@@ -69,14 +70,14 @@ start_link(Host, Opts) ->
+ gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
+
+ init([Host, Opts]) ->
+- {IP, State} = parse_options(Host, Opts),
+- NewOpts = [Host, {ip, IP} | Opts],
+- ejabberd_listener:add_listener(State#state.port, mod_proxy65_stream, NewOpts),
++ State = parse_options(Host, Opts),
++ NewOpts = [Host | Opts],
++ ejabberd_listener:add_listener({State#state.port, State#state.ip}, mod_proxy65_stream, NewOpts),
+ ejabberd_router:register_route(State#state.myhost),
+ {ok, State}.
+
+-terminate(_Reason, #state{myhost=MyHost, port=Port}) ->
+- catch ejabberd_listener:delete_listener(Port),
++terminate(_Reason, #state{myhost=MyHost, port=Port, ip=IP}) ->
++ catch ejabberd_listener:delete_listener({Port, IP}),
+ ejabberd_router:unregister_route(MyHost),
+ ok.
+
+@@ -203,12 +204,13 @@ parse_options(ServerHost, Opts) ->
+ end,
+ StrIP = inet_parse:ntoa(IP),
+ StreamAddr = [{"jid", MyHost}, {"host", StrIP}, {"port", integer_to_list(Port)}],
+- {IP, #state{myhost = MyHost,
++ #state{myhost = MyHost,
+ serverhost = ServerHost,
+ name = Name,
+ port = Port,
++ ip = IP,
+ stream_addr = StreamAddr,
+- acl = ACL}}.
++ acl = ACL}.
+
+ %% Return the IP of the proxy host, or if not found, the ip of the xmpp domain
+ get_proxy_or_domainip(ServerHost, MyHost) ->
diff --git a/chat/ejabberd/patches/patch-ai b/chat/ejabberd/patches/patch-ai
new file mode 100644
index 00000000000..b3ae478b4aa
--- /dev/null
+++ b/chat/ejabberd/patches/patch-ai
@@ -0,0 +1,158 @@
+$NetBSD: patch-ai,v 1.1 2008/11/12 13:13:59 martti Exp $
+
+Modified to use IPv6/v4 patch (https://support.process-one.net/browse/EJAB-389)
+
+--- src/web/ejabberd_web_admin.erl.orig 2008-08-27 12:37:52.000000000 +0300
++++ src/web/ejabberd_web_admin.erl
+@@ -1806,15 +1806,21 @@ get_node(global, Node, ["ports"], Query,
+ ok;
+ {'EXIT', _Reason} ->
+ error;
++ {is_added, ok} ->
++ ok;
++ {is_added, {error, Reason}} ->
++ {error, io_lib:format("~p", [Reason])};
+ _ ->
+ nothing
+ end,
++ %% TODO: This sorting does not work when [{{Port, IP}, Module, Opts}]
+ NewPorts = lists:sort(
+ rpc:call(Node, ejabberd_config, get_local_option, [listen])),
+ [?XC("h1", ?T("Listened Ports at ") ++ atom_to_list(Node))] ++
+ case Res of
+ ok -> [?CT("Submitted"), ?P];
+ error -> [?CT("Bad format"), ?P];
++ {error, ReasonT} -> [?CT("Problem: "), ?C(ReasonT), ?P];
+ nothing -> []
+ end ++
+ [?XAE("form", [{"action", ""}, {"method", "post"}],
+@@ -2052,58 +2058,76 @@ node_ports_to_xhtml(Ports, Lang) ->
+ [?XE("thead",
+ [?XE("tr",
+ [?XCT("td", "Port"),
++ ?XCT("td", "IP"),
+ ?XCT("td", "Module"),
+ ?XCT("td", "Options")
+ ])]),
+ ?XE("tbody",
+ lists:map(
+- fun({Port, Module, Opts} = _E) ->
+- SPort = integer_to_list(Port),
++ fun({PortIP, Module, Opts} = _E) ->
++ {_Port, SPort, _TIP, SIP, SSPort, OptsClean} =
++ get_port_data(PortIP, Opts),
+ SModule = atom_to_list(Module),
+ %%ID = term_to_id(E),
+ ?XE("tr",
+- [?XC("td", SPort),
+- ?XE("td", [?INPUT("text", "module" ++ SPort,
+- SModule)]),
+- ?XE("td", [?INPUTS("text", "opts" ++ SPort,
+- term_to_string(Opts), "40")]),
+- ?XE("td", [?INPUTT("submit", "add" ++ SPort,
++ [?XAE("td", [{"size", "6"}], [?C(SPort)]),
++ ?XAE("td", [{"size", "15"}], [?C(SIP)]),
++ ?XE("td", [?INPUTS("text", "module" ++ SSPort,
++ SModule, "15")]),
++ ?XE("td", [?INPUTS("text", "opts" ++ SSPort,
++ term_to_string(OptsClean), "40")]),
++ ?XE("td", [?INPUTT("submit", "add" ++ SSPort,
+ "Update")]),
+- ?XE("td", [?INPUTT("submit", "delete" ++ SPort,
++ ?XE("td", [?INPUTT("submit", "delete" ++ SSPort,
+ "Delete")])
+ ]
+ )
+ end, Ports) ++
+ [?XE("tr",
+ [?XE("td", [?INPUTS("text", "portnew", "", "6")]),
+- ?XE("td", [?INPUT("text", "modulenew", "")]),
+- ?XE("td", [?INPUTS("text", "optsnew", "", "40")]),
++ ?XE("td", [?INPUTS("text", "ipnew", "0.0.0.0", "15")]),
++ ?XE("td", [?INPUTS("text", "modulenew", "", "17")]),
++ ?XE("td", [?INPUTS("text", "optsnew", "[]", "40")]),
+ ?XAE("td", [{"colspan", "2"}],
+ [?INPUTT("submit", "addnew", "Add New")])
+ ]
+ )]
+ )]).
+
++get_port_data(PortIP, Opts) ->
++ {Port, IPT, IPS, _IPV, OptsClean} = ejabberd_listener:parse_listener_portip(PortIP, Opts),
++ SPort = io_lib:format("~p", [Port]),
++
++ SSPort = lists:flatten(
++ lists:map(
++ fun(N) -> io_lib:format("~.16b", [N]) end,
++ binary_to_list(crypto:md5(SPort++IPS)))),
++ {Port, SPort, IPT, IPS, SSPort, OptsClean}.
+
+ node_ports_parse_query(Node, Ports, Query) ->
+ lists:foreach(
+- fun({Port, _Module1, _Opts1}) ->
+- SPort = integer_to_list(Port),
+- case lists:keysearch("add" ++ SPort, 1, Query) of
++ fun({PortIP, _Module1, Opts1}) ->
++ {Port, _SPort, TIP, _SIP, SSPort, _OptsClean} =
++ get_port_data(PortIP, Opts1),
++ case lists:keysearch("add" ++ SSPort, 1, Query) of
+ {value, _} ->
++ PortIP2 = {Port, TIP},
+ {{value, {_, SModule}}, {value, {_, SOpts}}} =
+- {lists:keysearch("module" ++ SPort, 1, Query),
+- lists:keysearch("opts" ++ SPort, 1, Query)},
++ {lists:keysearch("module" ++ SSPort, 1, Query),
++ lists:keysearch("opts" ++ SSPort, 1, Query)},
+ Module = list_to_atom(SModule),
+ {ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
+ {ok, Opts} = erl_parse:parse_term(Tokens),
+- rpc:call(Node, ejabberd_listener, delete_listener, [Port]),
+- rpc:call(Node, ejabberd_listener, add_listener, [Port, Module, Opts]),
+- throw(submitted);
++ rpc:call(Node, ejabberd_listener, delete_listener,
++ [PortIP2]),
++ R=rpc:call(Node, ejabberd_listener, add_listener,
++ [PortIP2, Module, Opts]),
++ throw({is_added, R});
+ _ ->
+- case lists:keysearch("delete" ++ SPort, 1, Query) of
++ case lists:keysearch("delete" ++ SSPort, 1, Query) of
+ {value, _} ->
+- rpc:call(Node, ejabberd_listener, delete_listener, [Port]),
++ rpc:call(Node, ejabberd_listener, delete_listener,
++ [PortIP]),
+ throw(submitted);
+ _ ->
+ ok
+@@ -2113,17 +2137,28 @@ node_ports_parse_query(Node, Ports, Quer
+ case lists:keysearch("addnew", 1, Query) of
+ {value, _} ->
+ {{value, {_, SPort}},
++ {value, {_, STIP}}, %% It is a string that may represent a tuple
+ {value, {_, SModule}},
+ {value, {_, SOpts}}} =
+ {lists:keysearch("portnew", 1, Query),
++ lists:keysearch("ipnew", 1, Query),
+ lists:keysearch("modulenew", 1, Query),
+ lists:keysearch("optsnew", 1, Query)},
+- Port = list_to_integer(SPort),
++ {ok, Toks, _} = erl_scan:string(SPort ++ "."),
++ {ok, Port2} = erl_parse:parse_term(Toks),
++ {ok, ToksIP, _} = erl_scan:string(STIP ++ "."),
++ STIP2 = case erl_parse:parse_term(ToksIP) of
++ {ok, IPTParsed} -> IPTParsed;
++ {error, _} -> STIP
++ end,
+ Module = list_to_atom(SModule),
+ {ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
+ {ok, Opts} = erl_parse:parse_term(Tokens),
+- rpc:call(Node, ejabberd_listener, add_listener, [Port, Module, Opts]),
+- throw(submitted);
++ {Port2, _SPort, IP2, _SIP, _SSPort, OptsClean} =
++ get_port_data({Port2, STIP2}, Opts),
++ R=rpc:call(Node, ejabberd_listener, add_listener,
++ [{Port2, IP2}, Module, OptsClean]),
++ throw({is_added, R});
+ _ ->
+ ok
+ end.