X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=develdoc.txt;h=43804122b91a31fab73cc4fc62c99e9ed4bba9c1;hb=45cb83f89c693815421792b99d7c2329ad3bb322;hp=d3ee6f75a084759158ada7aa5ccfa3c7e4a41016;hpb=78df329e73ab2c618089e73bdb8830c362fec196;p=libradsec.git diff --git a/develdoc.txt b/develdoc.txt index d3ee6f7..4380412 100644 --- a/develdoc.txt +++ b/develdoc.txt @@ -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().