From c248bffd54ed08034f22e98e13b9612f685592d4 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Tue, 11 Nov 2003 20:51:04 +0000 Subject: * doc/dev.tex: Developers documentation (not completed) * src/ejabberd_c2s.erl: Better handling of malformed JIDs * src/mod_register.erl (try_register/2): Now returns "jid malformed" error if user name is invalid SVN Revision: 174 --- doc/dev.html | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 doc/dev.html (limited to 'doc/dev.html') diff --git a/doc/dev.html b/doc/dev.html new file mode 100644 index 000000000..ad12f39dd --- /dev/null +++ b/doc/dev.html @@ -0,0 +1,364 @@ + + +Ejabberd Developers Guide + + + + + + + + + + + + + +

Ejabberd Developers Guide

+ +

Alexey Shchepin
+mailto:alexey@sevcom.net
+xmpp:aleksey@jabber.ru

+ +

September 10, 2003

+ + + + +

+
+ + + + +

Table of Contents

+ + + + + +

1  Introduction

+ + +ejabberd is a Free and Open Source fault-tolerant distributed Jabber +server. It is writen mostly in Erlang.
+
+The main features of ejabberd is: + + + +

1.1  How it works

+ + +A Jabber domain is served by one or more ejabberd nodes. These nodes can +be run on different machines that are connected via a network. They all must +have the ability to connect to port 4369 of all another nodes, and must have +the same magic cookie (see Erlang/OTP documentation, in other words the file +~ejabberd/.erlang.cookie must be the same on all nodes). This is +needed because all nodes exchange information about connected users, S2S +connections, registered services, etc...
+
+Each ejabberd node have following modules: + + + +

1.1.1  Router

+ +This module is the main router of Jabber packets on each node. It routes +them based on their destinations domains. It has two tables: local and global +routes. First, domain of packet destination searched in local table, and if it +found, then the packet is routed to appropriate process. If no, then it +searches in global table, and is routed to the appropriate ejabberd node or +process. If it does not exists in either tables, then it sent to the S2S +manager.
+
+ + +

1.1.2  Local Router

+ +This module routes packets which have a destination domain equal to this server +name. If destination JID has a non-empty user part, then it routed to the +session manager, else it is processed depending on it's content.
+
+ + +

1.1.3  Session Manager

+ +This module routes packets to local users. It searches for what user resource +packet must be sended via presence table. If this resource is connected to +this node, it is routed to C2S process, if it connected via another node, then +the packet is sent to session manager on that node.
+
+ + +

1.1.4  S2S Manager

+ +This module routes packets to other Jabber servers. First, it checks if an +open S2S connection from the domain of the packet source to the domain of +packet destination already exists. If it is open on another node, then it +routes the packet to S2S manager on that node, if it is open on this node, then +it is routed to the process that serves this connection, and if a connection +does not exist, then it is opened and registered.
+
+ + +

2  XML representation

+ + +Each XML stanza represented as following tuple: +
+XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
+        Name = string()
+        Attrs = [Attr]
+        Attr = {Key, Val}
+        Key = string()
+        Val = string()
+        ElementOrCDATA = XMLElement | CDATA
+        CDATA = {xmlcdata, string()}
+
E. g. this stanza: +
+<message to='test@conference.e.localhost' type='groupchat'>
+  <body>test</body>
+</message>
+
represented as following structure: +
+{xmlelement, "message",
+    [{"to", "test@conference.e.localhost"},
+     {"type", "groupchat"}],
+    [{xmlelement, "body",
+         [],
+         [{xmlcdata, "test"}]}]}}
+
+ + +

3  Module xml

+ + +
+element_to_string(El) -> string()
+
+El = XMLElement
+
Returns string representation of XML stanza El.
+
+
crypt(S) -> string()
+
+S = string()
+
Returns string which correspond to S with encoded XML special + characters.
+
+
remove_cdata(ECList) -> EList
+
+ECList = [ElementOrCDATA]
+EList = [XMLElement]
+
EList is a list of all non-CDATA elements of ECList.
+
+
get_path_s(El, Path) -> Res
+
+El = XMLElement
+Path = [PathItem]
+PathItem = PathElem | PathAttr | PathCDATA
+PathElem = {elem, Name}
+PathAttr = {attr, Name}
+PathCDATA = cdata
+Name = string()
+Res = string() | XMLElement
+
If Path is empty, then returns El. Else sequentially + consider elements of Path. Each element is one of: +
+ {elem, Name}
Name is name of subelement of + El, if such element exists, then this element considered in + following steps, else returns empty string. +
{attr, Name}
If El have attribute Name, then + returns value of this attribute, else returns empty string. +
cdata
Returns CDATA of El. +

+
+
TODO:
+
+         get_cdata/1, get_tag_cdata/1
+         get_attr/2, get_attr_s/2
+         get_tag_attr/2, get_tag_attr_s/2
+         get_subtag/2
+
+ + +

4  ejabberd modules

+ + + + +

4.1  gen_mod behaviour

+ + +TBD
+
+ + +

4.2  Module gen_iq_handler

+ + +The module gen_iq_handler allows to easily write handlers for IQ packets +of particular XML namespaces that addressed to server or to users bare JIDs.
+
+In this module the following functions are defined: +
+add_iq_handler(Component, NS, Module, Function, Type)
+
+Component = Module = Function = atom()
+NS = string()
+Type = no_queue | one_queue | parallel
+
Registers function Module:Function as handler for IQ packets that + contain child of namespace NS in Component. Queueing + discipline is Type. There are at least two components defined: +
+ ejabberd_local
Handles packets that addressed to server JID; +
ejabberd_sm
Handles packets that addressed to users bare JIDs. +
+
remove_iq_handler(Component, NS)
+
+Component = atom()
+NS = string()
+
Removes IQ handler for namespace NS from Component. +
+Handler function must have the following type: +
+Module:Function(From, To, IQ)
+
+From = To = jid()
+
+
+-module(mod_cputime).
+
+-behaviour(gen_mod).
+
+-export([start/1,
+         stop/0,
+         process_local_iq/3]).
+
+-include("ejabberd.hrl").
+-include("jlib.hrl").
+
+-define(NS_CPUTIME, "ejabberd:cputime").
+
+start(Opts) ->
+    IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
+    gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_CPUTIME,
+                                  ?MODULE, process_local_iq, IQDisc).
+
+stop() ->
+    gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_CPUTIME).
+
+process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+    case Type of
+        set ->
+            {iq, ID, error, XMLNS,
+             [SubEl, ?ERR_NOT_ALLOWED]};
+        get ->
+            CPUTime = element(1, erlang:statistics(runtime))/1000,
+            SCPUTime = lists:flatten(io_lib:format("~.3f", CPUTime)),
+            {iq, ID, result, XMLNS,
+             [{xmlelement, "query",
+               [{"xmlns", ?NS_CPUTIME}],
+               [{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
+    end.
+
+ + +

4.3  Services

+ + +TBD
+
+TODO: use proc_lib +
+-module(mod_echo).
+
+-behaviour(gen_mod).
+
+-export([start/1, init/1, stop/0]).
+
+-include("ejabberd.hrl").
+-include("jlib.hrl").
+
+start(Opts) ->
+    Host = gen_mod:get_opt(host, Opts, "echo." ++ ?MYNAME),
+    register(ejabberd_mod_echo, spawn(?MODULE, init, [Host])).
+
+init(Host) ->
+    ejabberd_router:register_local_route(Host),
+    loop(Host).
+
+loop(Host) ->
+    receive
+        {route, From, To, Packet} ->
+            ejabberd_router:route(To, From, Packet),
+            loop(Host);
+        stop ->
+            ejabberd_router:unregister_local_route(Host),
+            ok;
+        _ ->
+            loop(Host)
+    end.
+
+stop() ->
+    ejabberd_mod_echo ! stop,
+    ok.
+
+ + + +
+
This document was translated from LATEX by +HEVEA. +
+ + -- cgit v1.2.3