help-gnutls
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-gnutls] timeout?


From: Oliver Lupton
Subject: Re: [Help-gnutls] timeout?
Date: Mon, 05 Jun 2006 22:29:15 +0100
User-agent: Thunderbird 1.5.0.4 (X11/20060604)

mogorman wrote:
Oliver Lupton wrote:

mogorman wrote:

Hello
Can someone provide or explain to me how to use gnutls_recv with a timeout, or someway to acheive the same function?

Thanks
Mog


_______________________________________________
Help-gnutls mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/help-gnutls


I'm a little in a rush so sorry there's no examples.
There may be a easier way of doing this that's "good enough", but you can set the socket descriptors non-blocking which will cause gnutls_record_recv to always return immediately. You can then either go all the way and make your whole program use async sockets (a pain, if you've already written a lot), or you can write a wrapper for gnutls_record_recv to select() for the socket being readable, select() can timeout :)
I can do some examples soon if you need them, just ask :)

Cheers,
-ol

yes I would greatly appreciate it if you dont mind, im actually using a jabber library (iksemel) that uses gnutls and it is calling gnutls_recv and never timing out so i am going to have to change it there, but needless to say i have not used gnutls that much.

Mog


Okay, firstly setting a socket nonblocking:

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);

Once a socket is nonblocking, no calls to read(), write(), recv(), send() etc will ever block, they'll always return immediately. I'm assuming all the stuff giving gnutls the descriptor and so on is working already.

Now, the second way with a wrapper would be something like:

int my_read(gnutls_session_t session, char* buffer, int length, int timeout)
{
        int fd;
        fd_set rfds;
        struct timeval tv;

        fd = (int)gnutls_transport_get_ptr(session);
        tv.tv_sec = length;
        tv.tv_usec = 0;

        FD_ZERO(&rfds);
        FD_SET(fd, &rfds);
        
        int sr = select(fd+1, &rfds, NULL, NULL, &tv);
        
        if(sr == -1)
        {
                /* Shouldn't happen, select() error */
                return -1;
        }
        else if(sr)
        {
                int r = gnutls_record_recv(session, buffer, length);
                
/* Handle this as you would normally, probably just return it and let the caller handle it. */
                return r;
        }
        else
        {
                /* Timeout, however you want to indicate it */
        }
}

Having said that this would be an easy way, I think it may have some issues with the handshaking, a possible solution might be to not set the socket nonblocking until after the handshake is complete. But maybe someone else would have a neater solution? As for the fully-async way, I don't think I can really show it in one example. If you have some understanding of how asynchronous socket apps work then it shouldn't be too hard :)

Hope some of this helps

Cheers,
-ol




reply via email to

[Prev in Thread] Current Thread [Next in Thread]