Quantcast

Creating a timer within a module

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Creating a timer within a module

Alejandro Pérez Méndez
Hello,

I'm trying to extend the functionality of the trust router client which
is implemented in the trustrouter.c file (within the rlm_realm module)
by providing basic re-keying capabilities.

The intention is to create some sort of timer that calls the TIDC
library periodically (e.g. every 10 minutes) and refresh the REALM
structure (with the TLS keys). So far, this only happens when there is
traffic associated to that REALM once they keys have expired. Now, for
that periodical call, I need to create some sort of timer that calls me
back when the time has expired and let me invoke the TIDC library to
update the realm.

Since I don't want re-inventing the wheel here, is there any recommended
way of doing so? I could create a thread, but since you're using some
sort of thread pool, I don't want to do anything out of control here
which can lead to race conditions while writing to the realm list.

Thanks,
Alejandro
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Alan DeKok-2
On May 8, 2017, at 2:06 PM, Alejandro Pérez Méndez <[hidden email]> wrote:
> I'm trying to extend the functionality of the trust router client which is implemented in the trustrouter.c file (within the rlm_realm module) by providing basic re-keying capabilities.
>
> The intention is to create some sort of timer that calls the TIDC library periodically (e.g. every 10 minutes) and refresh the REALM structure (with the TLS keys). So far, this only happens when there is traffic associated to that REALM once they keys have expired. Now, for that periodical call, I need to create some sort of timer that calls me back when the time has expired and let me invoke the TIDC library to update the realm.
>
> Since I don't want re-inventing the wheel here, is there any recommended way of doing so? I could create a thread, but since you're using some sort of thread pool, I don't want to do anything out of control here which can lead to race conditions while writing to the realm list.

  You should create a thread in the modules initialization routine.  Then, call radius_event_list_corral() to get the main server event list.

  That thread can do updates.

  You will need to be sure that memory accesses are thread-safe.  How to do that... is not simple.  I've made some changes in realms.c, but I don't think they're finished.

  In the end, v3 isn't designed to have dynamic realm updates.  And fixing it will be almost impossible at this stage.

  Alan DeKok.


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Alejandro Pérez Méndez

>    You should create a thread in the modules initialization routine.  Then, call radius_event_list_corral() to get the main server event list.
>
>    That thread can do updates.

Thanks. I'll look into it. I didn't want to make changes to rlm_realm,
just to trustrouter.c. But if I need to create the thread there, so be it.

>    You will need to be sure that memory accesses are thread-safe.  How to do that... is not simple.  I've made some changes in realms.c, but I don't think they're finished.
>
>    In the end, v3 isn't designed to have dynamic realm updates.  And fixing it will be almost impossible at this stage.

I see. My code won't do anything different to what it is currently being
done in trustrouter.c... would there be any difference? I assume current
code can potentially be executed from different threads.

What I see is that trustrouter.c either:
1) Adds a new realm, which seems to be mutex protected by the tree itself.
2) Replaces one server pool with another one. This change does not seem
to be mutex protected
(https://github.com/FreeRADIUS/freeradius-server/blob/v3.0.x/src/modules/rlm_realm/trustrouter.c#L273)

I will only do 2), in exactly the same way as it is being done right
now, but within the event handler.

Alejandro
>
>    Alan DeKok.
>
>
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Alejandro Pérez Méndez


El 08/05/17 a las 21:18, Alejandro Pérez Méndez escribió:
>
>>    You should create a thread in the modules initialization routine.  
>> Then, call radius_event_list_corral() to get the main server event list.
>>
>>    That thread can do updates.
>
> Thanks. I'll look into it. I didn't want to make changes to rlm_realm,
> just to trustrouter.c. But if I need to create the thread there, so be
> it.

Hi Alan,

I've been trying to make this work, but I'm sure I'm doing something
wrong. When you say "You should create a thread in the modules
initialization routine." do you mean by using pthread_create() directly
or by using any of the thread primitives FR has (although those seem to
be intended only for handling REQUEST* objects).

I've also tried without creating a thread, but then the event's callback
seems to be called from the main server thread, precluding other tasks
to be executed until the callback is finished.
Even with a thread, how do I make events to be handled by that thread?
Or should the event trigger the execution of a thread?

Thanks,
Alejandro
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Alejandro Pérez Méndez

>>
>>>    You should create a thread in the modules initialization
>>> routine.  Then, call radius_event_list_corral() to get the main
>>> server event list.
>>>
>>>    That thread can do updates.
>>
>> Thanks. I'll look into it. I didn't want to make changes to
>> rlm_realm, just to trustrouter.c. But if I need to create the thread
>> there, so be it.
>
> Hi Alan,
>
> I've been trying to make this work, but I'm sure I'm doing something
> wrong. When you say "You should create a thread in the modules
> initialization routine." do you mean by using pthread_create()
> directly or by using any of the thread primitives FR has (although
> those seem to be intended only for handling REQUEST* objects).
>
> I've also tried without creating a thread, but then the event's
> callback seems to be called from the main server thread, precluding
> other tasks to be executed until the callback is finished.
> Even with a thread, how do I make events to be handled by that thread?
> Or should the event trigger the execution of a thread?

Ok I think I got it. Was your suggestion to use the event list for
having the timer functionality, but then on the event handler start/use
a custom thread for performing the lengthy operation?

Thanks
>
> Thanks,
> Alejandro

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Alan DeKok-2
On May 9, 2017, at 7:10 AM, Alejandro Pérez Méndez <[hidden email]> wrote:
> Ok I think I got it. Was your suggestion to use the event list for having the timer functionality, but then on the event handler start/use a custom thread for performing the lengthy operation?

  If the work to be done is small, it can just use the main thread, and the main event loop.

  If the work to be done is large, the module should start it's own thread, and use it's own event loop.

  Alan DeKok.


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Alejandro Pérez Méndez


El 09/05/17 a las 14:57, Alan DeKok escribió:
> On May 9, 2017, at 7:10 AM, Alejandro Pérez Méndez <[hidden email]> wrote:
>> Ok I think I got it. Was your suggestion to use the event list for having the timer functionality, but then on the event handler start/use a custom thread for performing the lengthy operation?
>    If the work to be done is small, it can just use the main thread, and the main event loop.
>
>    If the work to be done is large, the module should start it's own thread, and use it's own event loop.
Thanks. My case would be the second one, so would not need to call
radius_event_list_corral() as a new event loop must be created.

Alejandro

>
>    Alan DeKok.
>
>
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Alejandro Pérez Méndez

>> On May 9, 2017, at 7:10 AM, Alejandro Pérez Méndez <[hidden email]> wrote:
>>> Ok I think I got it. Was your suggestion to use the event list for
>>> having the timer functionality, but then on the event handler
>>> start/use a custom thread for performing the lengthy operation?
>>    If the work to be done is small, it can just use the main thread,
>> and the main event loop.
>>
>>    If the work to be done is large, the module should start it's own
>> thread, and use it's own event loop.
> Thanks. My case would be the second one, so would not need to call
> radius_event_list_corral() as a new event loop must be created.

It seems that an event loop do not serve my purposes, as it is not
thread-safe and I will be inserting from the REQUEST thread pool,
whereas consuming from the rekeyer thread (the one I create for my
module). I can obviously add a mutex but then REQUESTS handling might be
blocked for as long as a rekey can last (which is what I wanted to avoid
in the first place).

Would it be ok for FR standards to use a HEAP directly and have my
rekeyer thread consuming data from the HEAP and performing the specific
task of rekeying? In that way I can separate extracting from the HEAP
(mutex protected) than executing the rekey (does not need to be protected).

I'm asking since I will eventually want this code to be merged, so I'd
better know beforehand :).

Alejandro


>
> Alejandro
>
>>
>>    Alan DeKok.
>>
>>
>> -
>> List info/subscribe/unsubscribe? See
>> http://www.freeradius.org/list/devel.html
>
> -
> List info/subscribe/unsubscribe? See
> http://www.freeradius.org/list/devel.html

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Adam Bishop-2
On 10 May 2017, at 16:39, Alejandro Pérez Méndez <[hidden email]> wrote:
> It seems that an event loop do not serve my purposes, as it is not thread-safe and I will be inserting from the REQUEST thread pool, whereas consuming from the rekeyer thread (the one I create for my module). I can obviously add a mutex but then REQUESTS handling might be blocked for as long as a rekey can last (which is what I wanted to avoid in the first place).

Instead of handling it on a built in timer, does it change things if you trigger it via the control socket?

You could add some hooks so that radmin can trigger a rekey for a domain, then have an external process handle the timing.

Regards,

Adam Bishop

  gpg: E75B 1F92 6407 DFDF 9F1C  BF10 C993 2504 6609 D460

jisc.ac.uk

Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.

Jisc Services Limited is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under company number 2881024, VAT number GB 197 0632 86. The registered office is: One Castle Park, Tower Hill, Bristol BS2 0JA. T 0203 697 5800.  

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Creating a timer within a module

Alejandro Pérez Méndez

> On 10 May 2017, at 16:39, Alejandro Pérez Méndez <[hidden email]> wrote:
>> It seems that an event loop do not serve my purposes, as it is not thread-safe and I will be inserting from the REQUEST thread pool, whereas consuming from the rekeyer thread (the one I create for my module). I can obviously add a mutex but then REQUESTS handling might be blocked for as long as a rekey can last (which is what I wanted to avoid in the first place).
> Instead of handling it on a built in timer, does it change things if you trigger it via the control socket?
>
> You could add some hooks so that radmin can trigger a rekey for a domain, then have an external process handle the timing.

I thought that at first, and indeed was my first approach. It was based
on special REQUESTS messages (using radtest) rather than control socket,
but after all pretty similar approach.
But it has the problem of requiring an external daemon to be up &
running, instead of being built-in. I had a conversation with Stefan and
he didn't like the idea of having an additional daemon (more hackish)...
and I agree. Furthermore, you loose some control over the whole process
(you need to somehow export which realms are dynamically created, when
they expire, etc.). Of course you can execvp() radmin from trustrouter.c
but that is quite ugly.

Regards,
Alejandro


>
> Regards,
>
> Adam Bishop
>
>    gpg: E75B 1F92 6407 DFDF 9F1C  BF10 C993 2504 6609 D460
>
> jisc.ac.uk
>
> Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.
>
> Jisc Services Limited is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under company number 2881024, VAT number GB 197 0632 86. The registered office is: One Castle Park, Tower Hill, Bristol BS2 0JA. T 0203 697 5800.
>
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
Loading...