summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/net-sendbuffer.c19
-rw-r--r--src/core/net-sendbuffer.h3
2 files changed, 18 insertions, 4 deletions
diff --git a/src/core/net-sendbuffer.c b/src/core/net-sendbuffer.c
index b74d178e..eb01aa47 100644
--- a/src/core/net-sendbuffer.c
+++ b/src/core/net-sendbuffer.c
@@ -37,6 +37,7 @@ NET_SENDBUF_REC *net_sendbuffer_create(GIOChannel *handle, int bufsize)
rec->send_tag = -1;
rec->handle = handle;
rec->bufsize = bufsize > 0 ? bufsize : DEFAULT_BUFFER_SIZE;
+ rec->def_bufsize = rec->bufsize;
buffers = g_slist_append(buffers, rec);
return rec;
@@ -61,7 +62,9 @@ static int buffer_send(NET_SENDBUF_REC *rec)
ret = net_transmit(rec->handle, rec->buffer, rec->bufpos);
if (ret < 0 || rec->bufpos == ret) {
/* error/all sent - don't try to send it anymore */
- g_free_and_null(rec->buffer);
+ rec->bufsize = rec->def_bufsize;
+ rec->buffer = g_realloc(rec->buffer, rec->bufsize);
+ rec->bufpos = 0;
return TRUE;
}
@@ -91,8 +94,16 @@ static int buffer_add(NET_SENDBUF_REC *rec, const void *data, int size)
rec->bufpos = 0;
}
- if (rec->bufpos+size > rec->bufsize)
- return FALSE;
+ while (rec->bufpos+size > rec->bufsize) {
+ if (rec->bufsize >= MAX_BUFFER_SIZE) {
+ if (!rec->dead)
+ g_warning("Dropping some data on an outgoing connection");
+ rec->dead = 1;
+ return FALSE;
+ }
+ rec->bufsize *= 2;
+ rec->buffer = g_realloc(rec->buffer, rec->bufsize);
+ }
memcpy(rec->buffer+rec->bufpos, data, size);
rec->bufpos += size;
@@ -110,7 +121,7 @@ int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size)
g_return_val_if_fail(data != NULL, -1);
if (size <= 0) return 0;
- if (rec->buffer == NULL) {
+ if (rec->buffer == NULL || rec->bufpos == 0) {
/* nothing in buffer - transmit immediately */
ret = net_transmit(rec->handle, data, size);
if (ret < 0) return -1;
diff --git a/src/core/net-sendbuffer.h b/src/core/net-sendbuffer.h
index f492821e..3c377110 100644
--- a/src/core/net-sendbuffer.h
+++ b/src/core/net-sendbuffer.h
@@ -2,6 +2,7 @@
#define __NET_SENDBUFFER_H
#define DEFAULT_BUFFER_SIZE 8192
+#define MAX_BUFFER_SIZE 1048576
struct _NET_SENDBUF_REC {
GIOChannel *handle;
@@ -10,6 +11,8 @@ struct _NET_SENDBUF_REC {
int bufsize;
int bufpos;
char *buffer; /* Buffer is NULL until it's actually needed. */
+ int def_bufsize;
+ unsigned int dead:1;
};
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE