MOO-Cows

moo-cows Topic: Authentication still blocks. Suggestions please.

Article #1108
Subject: Authentication still blocks. Suggestions please.
Author: Mark O'Neil
Posted: 4/9/2001 08:04:46 AM

Following the sample in extensions.c I have constructed the below code.

Suggestions please.

Thank you,
-m


Running the moo-server as a foreground process on my server and entering
';read_auth(#176)' in my MOO client, I get the following displayed in my
telnet console:

***** starting bf_read_auth.
***** starting auth_suspender.
***** finished auth_suspender.

The server does not block at this point, I can enter other commands in my
MOO client and they are processed, but the auth_readalble is not performed
until I hit return in the telnet console after which I get:

***** starting auth_readable.
***** starting auth_sc.

At this point the server still blocks until I process the authentication
request (via the client), after which I get:

***** finished auth_sc.auth_results:[Mark A. O'Neil]
***** resume task.

Code follows:


typedef struct auth_waiter {
    struct auth_waiter *next;
    vm the_vm;
} auth_waiter;

static auth_waiter *waiters = 0;



static void
auth_readable(int fd, void *data)
{
    Var v;
    auth_waiter *w;
       shandle *h = find_shandle(current_who);

    const char *auth_results;

    printf("***** starting auth_readable.\n");
    if (data != &waiters)
        panic("AUTH_READABLE: Bad data!");

    if (!waiters) {
        errlog("AUTH_READABLE: Nobody cares!\n");
        return;
    }

    printf("***** starting auth_sc.\n");

    auth_results = auth_sc(h->nhandle);

/* I have replaced the above call with the code */
/* from auth_sc with no change in performance */

    printf("***** finished auth_sc.auth_results:[%s]\n", auth_results);

    v.type = TYPE_STR;
    v.v.str = str_dup(auth_results);
     printf("***** resume task.\n");

    resume_task(waiters->the_vm, v);
    w = waiters->next;
    myfree(waiters, M_TASK);
    waiters = w;
    if (!waiters)
      network_unregister_fd(0);
}

static enum error
auth_suspender(vm the_vm, void *data)
{
    auth_waiter *w = data;

     printf("***** starting auth_suspender.\n");

    if (!waiters)
    network_register_fd(0, auth_readable, 0, &waiters);

    w->the_vm = the_vm;
    w->next = waiters;
    waiters = w;
     printf("***** finished auth_suspender.\n");

    return E_NONE;
}

const char *
auth_sc(network_handle nh)
{

/*  Grab the request parameters we need to authenticate the       */
/*  client.                                                       */

/*  Get the ticket from the client machine                        */

/*  Unpack the ticket */

/*  Validate the Kerberos ticket */

    return results;

}


Responses:

Article #1109
Subject: Re: Authentication still blocks. Suggestions please.
Author: Andrew Wendt
Posted: 4/9/2001 05:57:45 PM

On Monday 09 April 2001 09:04, Mark O'Neil wrote:
> Following the sample in extensions.c I have constructed the below code.
>
> Suggestions please.

[...snip...]
> ***** starting auth_readable.
> ***** starting auth_sc.
>
> At this point the server still blocks until I process the authentication
> request (via the client), after which I get:
>
> ***** finished auth_sc.auth_results:[Mark A. O'Neil]
> ***** resume task.
[...snip...]

I'm guessing that auth_sc does something which blocks the server. The server
isn't running your code in another thread or anything, so the whole thing
stops while auth_sc runs.

I don't know exactly what auth_sc is doing, but I guess it's network stuff...

One of your problems (and the reason you need to hit enter in your telnet
session) is your:
network_register_fd(0, auth_readable, 0, &waiters);

This is saying, call the function auth_readable with the data in &waiters
when there's activity on fd 0, which happens to be standard input.

This is what network_register_fd looks like:
network_register_fd(int fd, network_fd_callback readable,
                    network_fd_callback writable, void *data)

Say you wanted to do something which might take a non-trivial amount of time
like opening a network connection to some other computer. What should
probably happen is:

auth_suspender records whatever context it needs to in structure w, then
opens the network connection in non-blocking mode. My man page for connect()
says the socket will become writable when the connection is established. So
you would do something like:

network_register_fd(my_socket_fd, NULL, auth_writable, &waiters)

You'd then return, and the server would keep running and call auth_writable
when the connection was established, with the void *data pointing to the
correct member of the list waiters. It can do whatever it wants and call
network_unregister_fd() on that socket.

I guess that was sort of a dumb example, since after that you'd probably want
to read and write some commands/responses after the socket was connected, and
that would take a nontrivial amount of time too.

What I did when I played with non-blocking hostname lookups is fork() a new
child process to do the lookup, with a pipe() linking the child to the
server. network_register_fd() was told to wait for the pipe being readable.

Since the child ran in a seperate process, it could do whatever it wanted and
not block the server. When it was done, it sends the results back through the
pipe and exits.

If you had to do a whole series of blocking operations, that might be a
better choice.

> static enum error
> auth_suspender(vm the_vm, void *data)
> {
>     auth_waiter *w = data;
>
>      printf("***** starting auth_suspender.\n");
>
>     if (!waiters)
>     network_register_fd(0, auth_readable, 0, &waiters);
>
>     w->the_vm = the_vm;
>     w->next = waiters;
>     waiters = w;
>      printf("***** finished auth_suspender.\n");
>
>     return E_NONE;
> }
>
> const char *
> auth_sc(network_handle nh)
> {
>
> /*  Grab the request parameters we need to authenticate the       */
> /*  client.                                                       */
>
> /*  Get the ticket from the client machine                        */
>
> /*  Unpack the ticket */
>
> /*  Validate the Kerberos ticket */
>
>     return results;
>
> }

TTFN
Andy



MOO-Cows Home