summaryrefslogtreecommitdiff
path: root/packages/gsm/files/0003-Correctly-segment-incoming-usock-data-into-packets.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/gsm/files/0003-Correctly-segment-incoming-usock-data-into-packets.patch')
-rw-r--r--packages/gsm/files/0003-Correctly-segment-incoming-usock-data-into-packets.patch77
1 files changed, 77 insertions, 0 deletions
diff --git a/packages/gsm/files/0003-Correctly-segment-incoming-usock-data-into-packets.patch b/packages/gsm/files/0003-Correctly-segment-incoming-usock-data-into-packets.patch
new file mode 100644
index 0000000000..984acc9369
--- /dev/null
+++ b/packages/gsm/files/0003-Correctly-segment-incoming-usock-data-into-packets.patch
@@ -0,0 +1,77 @@
+From 8af1bb4a0d0df9baa80859c5f7f56cbd7634aded Mon Sep 17 00:00:00 2001
+From: Andrzej Zaborowski <balrog@zabor.org>
+Date: Wed, 19 Sep 2007 14:06:19 +0200
+Subject: [PATCH] Correctly segment incoming usock data into packets, handler short reads.
+
+---
+ include/gsmd/gsmd.h | 2 ++
+ src/gsmd/usock.c | 20 ++++++++++++++++----
+ 2 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/include/gsmd/gsmd.h b/include/gsmd/gsmd.h
+index 6ac9d8e..acec02a 100644
+--- a/include/gsmd/gsmd.h
++++ b/include/gsmd/gsmd.h
+@@ -95,6 +95,8 @@ struct gsmd_user {
+ struct gsmd *gsmd;
+ struct gsmd_fd gfd; /* the socket */
+ u_int32_t subscriptions; /* bitmaks of subscribed event groups */
++ char usock_fifo[1024];
++ int usock_len;
+
+ struct llist_head pb_readrg_list; /* our READRG phonebook list */
+ struct llist_head pb_find_list; /* our FIND phonebook list */
+diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
+index 32e98d0..bac5f0c 100644
+--- a/src/gsmd/usock.c
++++ b/src/gsmd/usock.c
+@@ -1529,14 +1529,15 @@ static int usock_rcv_pcmd(struct gsmd_user *gu, char *buf, int len)
+ static int gsmd_usock_user_cb(int fd, unsigned int what, void *data)
+ {
+ struct gsmd_user *gu = data;
++ struct gsmd_msg_hdr *gph;
+
+ /* FIXME: check some kind of backlog and limit it */
+
+ if (what & GSMD_FD_READ) {
+- char buf[1024];
+ int rcvlen;
+ /* read data from socket, determine what he wants */
+- rcvlen = read(fd, buf, sizeof(buf));
++ rcvlen = read(fd, gu->usock_fifo + gu->usock_len,
++ sizeof(gu->usock_fifo) - gu->usock_len);
+ if (rcvlen == 0) {
+ DEBUGP("EOF, this client has just vanished\n");
+ /* EOF, this client has just vanished */
+@@ -1549,8 +1550,18 @@ static int gsmd_usock_user_cb(int fd, unsigned int what, void *data)
+ return 0;
+ } else if (rcvlen < 0)
+ return rcvlen;
+- else
+- return usock_rcv_pcmd(gu, buf, rcvlen);
++
++ gu->usock_len += rcvlen;
++ gph = (struct gsmd_msg_hdr *) gu->usock_fifo;
++ while (gu->usock_len >= sizeof(*gph) &&
++ gu->usock_len >= sizeof(*gph) + gph->len) {
++ usock_rcv_pcmd(gu, gu->usock_fifo, gu->usock_len);
++ gu->usock_len -= sizeof(*gph) + gph->len;
++ memmove(gu->usock_fifo,
++ gu->usock_fifo + sizeof(*gph) +
++ gph->len,
++ gu->usock_len);
++ }
+ }
+
+ if (what & GSMD_FD_WRITE) {
+@@ -1609,6 +1620,7 @@ static int gsmd_usock_cb(int fd, unsigned int what, void *data)
+ newuser->gfd.cb = &gsmd_usock_user_cb;
+ newuser->gsmd = g;
+ newuser->subscriptions = 0xffffffff;
++ newuser->usock_len = 0;
+ INIT_LLIST_HEAD(&newuser->finished_ucmds);
+ INIT_LLIST_HEAD(&newuser->pb_readrg_list);
+ INIT_LLIST_HEAD(&newuser->pb_find_list);
+--
+1.5.2.1
+