radsecproxy-1.6.5.
[radsecproxy.git] / develdoc.txt
index d3ee6f7..4380412 100644 (file)
@@ -1,6 +1,7 @@
 radsecproxy documentation for developers
 
 1. Overall design
+=================
 
 At startup client and server configurations are read. Two lists
 are created, called clconfs and srvconfs. Both contain clsrvconf
@@ -35,7 +36,9 @@ xxxserverrd, where xxx is the transport name. The server reader
 is responsible for creating a server writer thread that takes care
 of sending RADIUS replies to a client.
 
+
 2. RADIUS message processing
+============================
 
 In 1 we described the threads used and the high level operations.
 We will now describe how RADIUS messages are processed and flow
@@ -135,7 +138,7 @@ reply by calling buf2radmsg(). If this fails or the message type
 is not one of Access Accept, Access Reject, Access Challenge or
 Accounting Response, the reply is ignored.
 
-If the request was a status-server message, it is simply removes
+If the request was a status-server message, it simply removes
 the request and returns.
 
 Next it will apply any rewritein rules and check TTL attribute if
@@ -152,15 +155,15 @@ sendreply() returns, we free the request from the server's
 request queue. This also means that the ID can be used for a new
 request.
 
-Now about sendreply(). All it does, is basically to assemble the
+Now about sendreply(). All it does is basically to assemble the
 reply message, take care of authenticators and set rq->replybuf
 to point to the result. After that it adds a pointer to rq to
-the clients reply queue, and signals the server writer who is
+the clients reply queue and signals the server writer who is
 responsible for sending replies to the client.
 
 The server writer is a separate thread created by the server reader,
 typically called something like xxxserverwr. All it does is to send
-whatever it finds in its replyq to the client and removes it. When
+whatever it finds in its replyq to the client and remove it. When
 the queue is empty it waits for a signal from a sendreply().
 
 The above shows the complete flow. It might be worth also looking a
@@ -194,14 +197,12 @@ Finally, in sendreply() rq->replybuf is created from rq->msg, and
 rq->msg is freed. rq->replybuf is kept so that if a duplicate request
 is received later, we can just return rq->replybuf.
 
-It appears that rq->buf created by sendrq() is stored until the
-request is replaced, it should be freed when replyh replaces rq->msg
-or in freerqoutdata().
+rq->buf is removed by freerqoutdata(), because then we will not try
+to send the request in rq->buf any more.
 
 Request structs should perhaps be freed when they "expire", rather
 than wait until a new request with the same ID comes along.
 
-
 x. Transports
 
 struct protodefs protodefs[] contains definitions of the different
@@ -279,3 +280,66 @@ addresses after initial startup.
 Can be defined it extra initialisation is needed for the transport.
 
 };
+
+
+3. Dynamic servers
+==================
+
+A server block can contain the 'dynamicLookupCommand' option, naming
+an executable file which will be executed (fork, exec) with the realm
+of the user being authenticated as its only argument.  The output from
+the program (read from stdout) is used as configuration text and
+parsed as if it was read from a configuration file.
+
+[XXX describe what happens when config is read -- set in
+createsubrealmservers() if the server block has the
+'dynamicLookupCommand' option]
+
+[XXX describe what happens when a packet is handled -- findserver()
+creating a realm object]
+
+[XXX describe the non-staticness of TLS connections to dynamically
+resolved servers -- tlsclientrd and IDLE_TIMEOUT]
+
+Dynamic freeing of resources
+----------------------------
+
+At the end of clientwr(), if server->dynamiclookuparg != NULL, the
+removeserversubrealms(list, server) function is called and normally
+so is freeclsrvconf(server).
+
+removeserversubrealms() traverses the list of realms (taking a lock on
+each realm) and calls _internal_removeserversubrealms(subrealm,
+server) on each subrealm.  If the list of subrealms is empty after
+this, it's being destroyed.
+
+The _internal_removeserversubrealms(realm list, SERVER) function
+traverses the list of realms and for each realm:
+
+  - increase the refcount on the realm
+
+  - take the lock on the realm
+
+  - for srv in realm->srvconfs: if srv == SERVER: decrease ref on realm
+
+  - free all servers in realm->srvconfs matching SERVER
+    (list_removedata() TODO: is this function correct?)
+
+  - same thing for realm->accsrvconfs as for srvconfs
+
+  - if none of the realm->srvconfs nor the realm->accsrvonfs has a
+    dynamiclookupcommand:
+
+    - for each srv in realm->srvconfs: free srv and decrease ref on realm
+
+    - destroy realm->srvconfs
+
+    - same thing for realm->accsrvconfs as for srvconfs
+
+    - release the realm lock
+
+    - decrease the refcount on the realm
+
+freeclsrvconf() performs 15 calls to free() and also invokes
+freegconfmstr(), freehostports(), regfree() and
+pthread_mutex_destroy().