Mercurial > dovecot > core-2.2
changeset 1710:f1377239867e HEAD
fixes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 22 Aug 2003 09:37:57 +0300 |
parents | 044fdf70f11a |
children | 293ec0d24009 |
files | src/lib-auth/auth-server-connection.c src/lib-auth/auth-server-connection.h src/lib-auth/auth-server-request.c |
diffstat | 3 files changed, 77 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-auth/auth-server-connection.c Fri Aug 22 08:06:53 2003 +0300 +++ b/src/lib-auth/auth-server-connection.c Fri Aug 22 09:37:57 2003 +0300 @@ -19,6 +19,8 @@ (sizeof(struct auth_client_request_continue) + \ AUTH_CLIENT_MAX_REQUEST_DATA_SIZE) +static void auth_server_connection_unref(struct auth_server_connection *conn); + static void update_available_auth_mechs(struct auth_client *client) { struct auth_server_connection *conn; @@ -104,9 +106,13 @@ return; /* we've got a full reply */ + conn->refcount++; conn->reply_received = FALSE; + auth_server_request_handle_reply(conn, &conn->reply, data); i_stream_skip(conn->input, conn->reply.data_size); + + auth_server_connection_unref(conn); } struct auth_server_connection * @@ -128,6 +134,7 @@ pool = pool_alloconly_create("Auth connection", 1024); conn = p_new(pool, struct auth_server_connection, 1); + conn->refcount = 1; conn->pool = pool; conn->client = client; @@ -163,6 +170,9 @@ struct auth_client *client = conn->client; struct auth_server_connection **pos; + if (conn->fd == -1) + return; + pos = &conn->client->connections; for (; *pos != NULL; pos = &(*pos)->next) { if (*pos == conn) { @@ -175,16 +185,17 @@ client->conn_waiting_handshake_count--; io_remove(conn->io); + conn->io = NULL; + + i_stream_close(conn->input); + o_stream_close(conn->output); + if (close(conn->fd) < 0) i_error("close(auth) failed: %m"); conn->fd = -1; auth_server_requests_remove_all(conn); - hash_destroy(conn->requests); - - i_stream_unref(conn->input); - o_stream_unref(conn->output); - pool_unref(conn->pool); + auth_server_connection_unref(conn); if (reconnect) auth_client_connect_missing_servers(client); @@ -195,6 +206,18 @@ } } +static void auth_server_connection_unref(struct auth_server_connection *conn) +{ + if (--conn->refcount > 0) + return; + + hash_destroy(conn->requests); + + i_stream_unref(conn->input); + o_stream_unref(conn->output); + pool_unref(conn->pool); +} + struct auth_server_connection * auth_server_connection_find_path(struct auth_client *client, const char *path) {
--- a/src/lib-auth/auth-server-connection.h Fri Aug 22 08:06:53 2003 +0300 +++ b/src/lib-auth/auth-server-connection.h Fri Aug 22 09:37:57 2003 +0300 @@ -20,6 +20,8 @@ struct auth_server_connection *next; pool_t pool; + int refcount; + struct auth_client *client; const char *path; int fd;
--- a/src/lib-auth/auth-server-request.c Fri Aug 22 08:06:53 2003 +0300 +++ b/src/lib-auth/auth-server-request.c Fri Aug 22 09:37:57 2003 +0300 @@ -47,6 +47,26 @@ return TRUE; } +static void auth_server_send_continue(struct auth_server_connection *conn, + struct auth_request *request, + const unsigned char *data, size_t size) +{ + struct auth_client_request_continue auth_request; + + /* send continued request to auth */ + auth_request.type = AUTH_CLIENT_REQUEST_CONTINUE; + auth_request.id = request->id; + auth_request.data_size = size; + + if (o_stream_send(conn->output, &auth_request, + sizeof(auth_request)) < 0 || + o_stream_send(conn->output, data, size) < 0) { + errno = conn->output->stream_errno; + i_warning("Error sending continue request to auth server: %m"); + auth_server_connection_destroy(conn, TRUE); + } +} + static struct auth_server_connection * get_next_plain_server(struct auth_server_connection *conn) { @@ -68,37 +88,43 @@ request = hash_lookup(conn->requests, POINTER_CAST(reply->id)); if (request == NULL) { - i_error("BUG: Auth server sent us reply with unknown ID %u", - reply->id); + /* We've already destroyed the request */ return; } switch (reply->result) { case AUTH_CLIENT_RESULT_SUCCESS: - if (conn == request->conn) - request->next_conn = NULL; - else { - i_assert(request->next_conn == conn); - request->conn = request->next_conn; - request->next_conn = NULL; + hash_remove(request->conn->requests, POINTER_CAST(request->id)); + if (request->next_conn != NULL) { + hash_remove(request->next_conn->requests, + POINTER_CAST(request->id)); } + request->conn = conn; + request->next_conn = NULL; break; case AUTH_CLIENT_RESULT_FAILURE: - if (request->plaintext_data == NULL) + hash_remove(conn->requests, POINTER_CAST(request->id)); + if (!request->retrying) break; - next = get_next_plain_server(conn); - if (next == NULL) - break; - - hash_remove(conn->requests, POINTER_CAST(request->id)); - hash_insert(next->requests, POINTER_CAST(request->id), request); + next = request->next_conn == NULL ? NULL : + get_next_plain_server(request->next_conn); if (conn == request->conn) request->conn = request->next_conn; + request->next_conn = NULL; + if (next == NULL) { + if (request->conn != NULL) { + /* the other one hasn't replied yet */ + return; + } + request->conn = conn; + break; + } + + hash_insert(next->requests, POINTER_CAST(request->id), request); request->next_conn = next; - request->retrying = TRUE; auth_server_send_new_request(next, request); return; @@ -106,15 +132,15 @@ if (!request->retrying) break; - auth_client_request_continue(request, request->plaintext_data, - request->plaintext_data_size); + auth_server_send_continue(conn, request, + request->plaintext_data, + request->plaintext_data_size); return; } request->callback(request, reply, data, request->context); if (reply->result != AUTH_CLIENT_RESULT_CONTINUE) { - hash_remove(conn->requests, POINTER_CAST(request->id)); i_free(request->plaintext_data); i_free(request); } @@ -169,7 +195,7 @@ void auth_client_request_continue(struct auth_request *request, const unsigned char *data, size_t data_size) { - struct auth_client_request_continue auth_request; + auth_server_send_continue(request->conn, request, data, data_size); if (request->mech == AUTH_MECH_PLAIN && request->plaintext_data == NULL) { @@ -185,21 +211,9 @@ POINTER_CAST(request->id), request); auth_server_send_new_request(request->next_conn, request); + request->retrying = TRUE; } } - - /* send continued request to auth */ - auth_request.type = AUTH_CLIENT_REQUEST_CONTINUE; - auth_request.id = request->id; - auth_request.data_size = data_size; - - if (o_stream_send(request->conn->output, &auth_request, - sizeof(auth_request)) < 0 || - o_stream_send(request->conn->output, data, data_size) < 0) { - errno = request->conn->output->stream_errno; - i_warning("Error sending continue request to auth server: %m"); - auth_server_connection_destroy(request->conn, TRUE); - } } void auth_client_request_abort(struct auth_request *request)