#define OUTBUF_THROTTLE_SIZE (1024*50)
static ARRAY_DEFINE(auth_client_connections, struct auth_client_connection *);
-static struct timeout *to_clients;
static void auth_client_connection_unref(struct auth_client_connection **_conn);
static void auth_client_input(struct auth_client_connection *conn);
return NULL;
}
-static void request_timeout(void *context ATTR_UNUSED)
-{
- struct auth_client_connection *const *clients;
-
- array_foreach(&auth_client_connections, clients) {
- struct auth_client_connection *client = *clients;
-
- if (client->request_handler != NULL) {
- auth_request_handler_check_timeouts(
- client->request_handler);
- }
- }
-}
-
void auth_client_connections_init(void)
{
i_array_init(&auth_client_connections, 16);
- to_clients = timeout_add(5000, request_timeout, NULL);
}
void auth_client_connections_deinit(void)
struct auth_client_connection **clients;
unsigned int i, count;
- if (to_clients != NULL)
- timeout_remove(&to_clients);
-
clients = array_get_modifiable(&auth_client_connections, &count);
for (i = count; i > 0; i--)
auth_client_connection_destroy(&clients[i-1]);
static void auth_request_handler_remove(struct auth_request_handler *handler,
struct auth_request *request)
{
+ i_assert(request->handler == handler);
+
hash_table_remove(handler->requests, POINTER_CAST(request->id));
auth_request_unref(&request);
}
-void auth_request_handler_check_timeouts(struct auth_request_handler *handler)
-{
- struct hash_iterate_context *iter;
- void *key, *value;
-
- iter = hash_table_iterate_init(handler->requests);
- while (hash_table_iterate(iter, &key, &value)) {
- struct auth_request *request = value;
-
- if (request->last_access + AUTH_REQUEST_TIMEOUT < ioloop_time)
- auth_request_handler_remove(handler, request);
- }
- hash_table_iterate_deinit(&iter);
-}
-
static void get_client_extra_fields(struct auth_request *request,
struct auth_stream_reply *reply)
{
auth_penalty_update(request->auth->penalty, request,
request->last_penalty + 1);
- request->last_access = ioloop_time;
+ auth_request_refresh_last_access(request);
aqueue_append(auth_failures, &request);
if (to_auth_failures == NULL) {
to_auth_failures =
auth_request_handler_remove(handler, request);
}
+static void auth_request_timeout(struct auth_request *request)
+{
+ auth_request_handler_remove(request->handler, request);
+}
+
static void auth_request_penalty_finish(struct auth_request *request)
{
timeout_remove(&request->to_penalty);
}
request = auth_request_new(handler->auth, mech, auth_callback, handler);
+ request->handler = handler;
request->connect_uid = handler->connect_uid;
request->client_pid = handler->client_pid;
request->id = id;
return FALSE;
}
+ request->to_abort = timeout_add(AUTH_REQUEST_TIMEOUT * 1000,
+ auth_request_timeout, request);
hash_table_insert(handler->requests, POINTER_CAST(id), request);
if (request->auth->set->ssl_require_client_cert &&
unsigned int connect_uid,
unsigned int client_pid);
-void auth_request_handler_check_timeouts(struct auth_request_handler *handler);
-
bool auth_request_handler_auth_begin(struct auth_request_handler *handler,
const char *args);
bool auth_request_handler_auth_continue(struct auth_request_handler *handler,
auth_request->refcount = 1;
auth_request->last_access = ioloop_time;
+
auth_request->auth = auth;
auth_request->passdb = auth->passdbs;
auth_request->userdb = auth->userdbs;
request->state = AUTH_REQUEST_STATE_FINISHED;
request->successful = TRUE;
- request->last_access = ioloop_time;
+ auth_request_refresh_last_access(request);
request->callback(request, AUTH_CLIENT_RESULT_SUCCESS,
data, data_size);
}
i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
request->state = AUTH_REQUEST_STATE_FINISHED;
- request->last_access = ioloop_time;
+ auth_request_refresh_last_access(request);
request->callback(request, AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
}
if (--request->refcount > 0)
return;
+ if (request->to_abort != NULL)
+ timeout_remove(&request->to_abort);
if (request->to_penalty != NULL)
timeout_remove(&request->to_penalty);
{
i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
- request->last_access = ioloop_time;
+ auth_request_refresh_last_access(request);
request->mech->auth_continue(request, data, data_size);
}
} T_END;
va_end(va);
}
+
+void auth_request_refresh_last_access(struct auth_request *request)
+{
+ request->last_access = ioloop_time;
+ if (request->to_abort != NULL)
+ timeout_reset(request->to_abort);
+}
struct auth_stream_reply *userdb_reply;
const struct mech_module *mech;
+ struct auth_request_handler *handler;
struct auth *auth;
struct auth_passdb *passdb;
struct auth_userdb *userdb;
struct ip_addr local_ip, remote_ip;
unsigned int local_port, remote_port;
- struct timeout *to_penalty;
+ struct timeout *to_abort, *to_penalty;
unsigned int last_penalty;
unsigned int initial_response_len;
const unsigned char *initial_response;
void auth_request_userdb_callback(enum userdb_result result,
struct auth_request *request);
+void auth_request_refresh_last_access(struct auth_request *request);
+
#endif