[dovecot-cvs] dovecot/src/pop3-login client-authenticate.c, 1.24,
1.25 client.c, 1.24, 1.25
cras at dovecot.org
cras at dovecot.org
Sun Aug 15 06:40:35 EEST 2004
Update of /home/cvs/dovecot/src/pop3-login
In directory talvi:/tmp/cvs-serv20173/pop3-login
Modified Files:
client-authenticate.c client.c
Log Message:
We never do blocking reads/writes to network anymore. Changed imap and pop3
processes to use a single I/O loop.
Not much tested yet, and currently LIST/LSUB may eat too much memory and
APPEND eats all CPU.
Index: client-authenticate.c
===================================================================
RCS file: /home/cvs/dovecot/src/pop3-login/client-authenticate.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- client-authenticate.c 30 Jul 2004 01:47:45 -0000 1.24
+++ client-authenticate.c 15 Aug 2004 03:40:32 -0000 1.25
@@ -58,7 +58,6 @@
client_send_line(client, msg != NULL ? t_strconcat("-ERR ", msg, NULL) :
"-ERR Authentication failed.");
- o_stream_flush(client->output);
/* get back to normal client input */
if (client->common.io != NULL)
@@ -91,6 +90,9 @@
const unsigned char *data, size_t size)
{
buffer_t *buf;
+ const void *buf_data;
+ size_t buf_size;
+ ssize_t ret;
t_push();
@@ -100,9 +102,11 @@
base64_encode(data, size, buf);
buffer_append(buf, "\r\n", 2);
- o_stream_send(client->output, buffer_get_data(buf, NULL),
- buffer_get_used_size(buf));
- o_stream_flush(client->output);
+ buf_data = buffer_get_data(buf, &buf_size);
+ if ((ret = o_stream_send(client->output, buf_data, buf_size) < 0))
+ client_destroy(client, "Disconnected");
+ else if ((size_t)ret != buf_size)
+ client_destroy(client, "Transmit buffer full");
t_pop();
}
@@ -393,6 +397,8 @@
buffer_get_data(apop_data, &info.initial_resp_size);
client_ref(client);
+ o_stream_uncork(client->output);
+
client->common.auth_request =
auth_client_request_new(auth_client, &client->auth_id, &info,
login_callback, client, &error);
Index: client.c
===================================================================
RCS file: /home/cvs/dovecot/src/pop3-login/client.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- client.c 6 Jul 2004 06:35:30 -0000 1.24
+++ client.c 15 Aug 2004 03:40:32 -0000 1.25
@@ -16,8 +16,13 @@
#include "hostpid.h"
#include "imem.h"
-/* max. length of input command line (spec says 512) */
-#define MAX_INBUF_SIZE 2048
+/* max. length of input command line (spec says 512), or max reply length in
+ SASL authentication */
+#define MAX_INBUF_SIZE 4096
+
+/* max. size of output buffer. if it gets full, the client is disconnected.
+ SASL authentication gives the largest output. */
+#define MAX_OUTBUF_SIZE 4096
/* Disconnect client after idling this many seconds */
#define CLIENT_LOGIN_IDLE_TIMEOUT 60
@@ -54,14 +59,54 @@
static void client_open_streams(struct pop3_client *client, int fd)
{
- client->input = i_stream_create_file(fd, default_pool, 8192, FALSE);
- client->output = o_stream_create_file(fd, default_pool, 1024, FALSE);
+ client->input = i_stream_create_file(fd, default_pool,
+ MAX_INBUF_SIZE, FALSE);
+ client->output = o_stream_create_file(fd, default_pool,
+ MAX_OUTBUF_SIZE, FALSE);
}
-static int cmd_stls(struct pop3_client *client)
+static void client_start_tls(struct pop3_client *client)
{
int fd_ssl;
+ fd_ssl = ssl_proxy_new(client->common.fd, &client->common.ip,
+ &client->common.proxy);
+ if (fd_ssl == -1) {
+ client_send_line(client, "-ERR TLS initialization failed.");
+ client_destroy(client, "TLS initialization failed.");
+ return;
+ }
+
+ client->tls = TRUE;
+ client->secured = TRUE;
+ client_set_title(client);
+
+ client->common.fd = fd_ssl;
+
+ i_stream_unref(client->input);
+ o_stream_unref(client->output);
+
+ client_open_streams(client, fd_ssl);
+ client->common.io = io_add(client->common.fd, IO_READ,
+ client_input, client);
+}
+
+static void client_output_starttls(void *context)
+{
+ struct pop3_client *client = context;
+ int ret;
+
+ if ((ret = o_stream_flush(client->output)) < 0) {
+ client_destroy(client, "Disconnected");
+ return;
+ }
+
+ if (ret > 0)
+ client_start_tls(client);
+}
+
+static int cmd_stls(struct pop3_client *client)
+{
if (client->tls) {
client_send_line(client, "-ERR TLS is already active.");
return TRUE;
@@ -72,36 +117,21 @@
return TRUE;
}
- client_send_line(client, "+OK Begin TLS negotiation now.");
- o_stream_flush(client->output);
-
- /* must be removed before ssl_proxy_new(), since it may
- io_add() the same fd. */
+ /* remove input handler, SSL proxy gives us a new fd. we also have to
+ remove it in case we have to wait for buffer to be flushed */
if (client->common.io != NULL) {
io_remove(client->common.io);
client->common.io = NULL;
}
- fd_ssl = ssl_proxy_new(client->common.fd, &client->common.ip,
- &client->common.proxy);
- if (fd_ssl != -1) {
- client->tls = TRUE;
- client->secured = TRUE;
- client_set_title(client);
-
- client->common.fd = fd_ssl;
-
- i_stream_unref(client->input);
- o_stream_unref(client->output);
-
- client_open_streams(client, fd_ssl);
- client->common.io = io_add(client->common.fd, IO_READ,
- client_input, client);
+ client_send_line(client, "+OK Begin TLS negotiation now.");
+ if (o_stream_get_buffer_used_size(client->output) != 0) {
+ /* the buffer has to be flushed */
+ o_stream_set_flush_callback(client->output,
+ client_output_starttls, client);
} else {
- client_send_line(client, "-ERR TLS initialization failed.");
- client_destroy(client, "TLS initialization failed.");
+ client_start_tls(client);
}
-
return TRUE;
}
@@ -184,7 +214,7 @@
}
if (client_unref(client))
- o_stream_flush(client->output);
+ o_stream_uncork(client->output);
}
static void client_destroy_oldest(void)
@@ -347,8 +377,18 @@
void client_send_line(struct pop3_client *client, const char *line)
{
- o_stream_send_str(client->output, line);
- o_stream_send(client->output, "\r\n", 2);
+ struct const_iovec iov[2];
+ ssize_t ret;
+
+ iov[0].iov_base = line;
+ iov[0].iov_len = strlen(line);
+ iov[1].iov_base = "\r\n";
+ iov[1].iov_len = 2;
+
+ if ((ret = o_stream_sendv(client->output, iov, 2)) < 0)
+ client_destroy(client, "Disconnected");
+ else if ((size_t)ret != iov[0].iov_len + iov[1].iov_len)
+ client_destroy(client, "Transmit buffer full");
}
void client_syslog(struct pop3_client *client, const char *text)
More information about the dovecot-cvs
mailing list