void proto1_sending(int events, int fd, void *closure, const struct timeval *t) { struct proto1_state *state = closure; unsigned char request_code = 1; int rv; rv = write(state->sock, &request_code, sizeof(request_code)); if (rv == -1) { if (errno != EINTR && errno != EAGAIN) { state->error = errno; } else if ((rv = gfarm_eventqueue_add_event(state->q, state->writable, NULL)) != 0) { state->error = rv; } else { return; /* go to proto1_sending() */ } } else { if ((rv = gfarm_eventqueue_add_event(state->q, state->readable, NULL)) == 0) { return; /* go to proto1_receiving() */ } state->error = rv; } if (state->continuation != NULL) (*state->continuation)(state->closure); }
/* this function returns 1, if an event is added */ static int gssInitiateSecurityContextSwitch( struct gfarmGssInitiateSecurityContextState *state) { int rv; struct timeval timeout; if (GSS_ERROR(state->majStat)) { return 0; } if (state->majStat & GSS_S_CONTINUE_NEEDED) { timeout.tv_sec = GFARM_GSS_AUTH_TIMEOUT; timeout.tv_usec = 0; rv = gfarm_eventqueue_add_event(state->q, state->readable, &timeout); if (rv == 0) { /* go to gfarmGssInitiateSecurityContextReceiveToken() */ return 1; } gflog_auth_error(GFARM_MSG_1000621, "gfarm:gssInitiateSecurityContextSwitch(): %s", strerror(rv)); state->majStat = GSS_S_FAILURE; state->minStat = GFSL_DEFAULT_MINOR_ERROR; } else { state->completed = 1; } return 0; }
int proto1_request_multiplexed(struct gfarm_eventqueue *q, int peer_socket, void (*continuation)(void *), void *closure, struct proto1_state **statepp) { struct proto1_state *state = malloc(sizeof(*state)); int rv = ENOMEM; if (state == NULL) return (ENOMEM); state->writable = gfarm_fd_event_alloc(GFARM_EVENT_WRITE, peer_socket, proto1_sending, state); if (state->writable != NULL) { state->readable = gfarm_fd_event_alloc( GFARM_EVENT_READ, peer_socket, proto1_receiving, state); if (state->readable != NULL) { state->q = q; state->sock = peer_socket; state->continuation = continuation; state->closure = closure; state->error = 0; rv = gfarm_eventqueue_add_event(q, state->writable, NULL); if (rv == 0) { *statepp = state; return (0); /* go to proto1_sending() */ } gfarm_event_free(state->readable); } gfarm_event_free(state->writable); } free(state); return (rv); }
void proto1_receiving(int events, int fd, void *closure, const struct timeval *t) { struct proto1_state *state = closure; int rv; rv = read(state->sock, &state->result, sizeof(state->result)); if (rv == -1) { if (errno != EINTR && errno != EAGAIN) state->error = errno; else if ((rv = gfarm_eventqueue_add_event(state->q, state->readable, NULL)) != 0) { state->error = rv; } } if (state->continuation != NULL) (*state->continuation)(state->closure); }
/* this function returns 1, if an event is added */ static int gssInitiateSecurityContextNext( struct gfarmGssInitiateSecurityContextState *state) { OM_uint32 minStat2; int rv; static const char diag[] = "gssInitiateSecurityContextNext()"; gfarm_mutex_lock(&gss_mutex, diag, gssDiag); state->majStat = gss_init_sec_context(&state->minStat, state->cred, &state->sc, state->acceptorName, GSS_C_NO_OID, state->reqFlag, 0, GSS_C_NO_CHANNEL_BINDINGS, state->itPtr, state->actualMechType, state->otPtr, &state->retFlag, &state->timeRet); gfarm_mutex_unlock(&gss_mutex, diag, gssDiag); if (state->itPtr->length > 0) gss_release_buffer(&minStat2, state->itPtr); if (state->otPtr->length > 0) { rv = gfarm_eventqueue_add_event(state->q, state->writable, NULL); if (rv == 0) { /* go to gfarmGssInitiateSecurityContextSendToken() */ return 1; } gflog_auth_error(GFARM_MSG_1000622, "gfarm:gssInitiateSecurityContextNext(): %s", strerror(rv)); state->majStat = GSS_S_FAILURE; state->minStat = GFSL_DEFAULT_MINOR_ERROR; } return gssInitiateSecurityContextSwitch(state); }