aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2019-05-06 13:53:18 +0000
committerMarc-André Lureau <marcandre.lureau@gmail.com>2019-05-06 13:53:18 +0000
commiteeaff9cf6f3251a5558bb541a043d1db58ff6812 (patch)
tree718d1bc84a290cea54ff0fc899b1b13c2471b3a3
parent0e79ba48567ccfb3cc2cf2e98cce8811eee7e455 (diff)
parent9da0da837780f825b5db31db6620492f8b7cd5d6 (diff)
downloadslirp-eeaff9cf6f3251a5558bb541a043d1db58ff6812.zip
slirp-eeaff9cf6f3251a5558bb541a043d1db58ff6812.tar.gz
slirp-eeaff9cf6f3251a5558bb541a043d1db58ff6812.tar.bz2
Merge branch 'emu-fix' into 'master'
Memory fixes for slirp tcp_emu() See merge request slirp/libslirp!6
-rw-r--r--src/tcp_subr.c60
1 files changed, 28 insertions, 32 deletions
diff --git a/src/tcp_subr.c b/src/tcp_subr.c
index 7ab3ab2..d6dd133 100644
--- a/src/tcp_subr.c
+++ b/src/tcp_subr.c
@@ -629,48 +629,43 @@ int tcp_emu(struct socket *so, struct mbuf *m)
struct socket *tmpso;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
- struct sbuf *so_rcv = &so->so_rcv;
+ char *eol = g_strstr_len(m->m_data, m->m_len, "\r\n");
- if (m->m_len >
- so_rcv->sb_datalen - (so_rcv->sb_wptr - so_rcv->sb_data)) {
+ if (!eol) {
return 1;
}
- memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
- so_rcv->sb_wptr += m->m_len;
- so_rcv->sb_rptr += m->m_len;
- m->m_data[m->m_len] = 0; /* NULL terminate */
- if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) {
- if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) {
- HTONS(n1);
- HTONS(n2);
- /* n2 is the one on our host */
- for (tmpso = slirp->tcb.so_next; tmpso != &slirp->tcb;
- tmpso = tmpso->so_next) {
- if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr &&
- tmpso->so_lport == n2 &&
- tmpso->so_faddr.s_addr == so->so_faddr.s_addr &&
- tmpso->so_fport == n1) {
- if (getsockname(tmpso->s, (struct sockaddr *)&addr,
- &addrlen) == 0)
- n2 = addr.sin_port;
- break;
- }
+ *eol = '\0';
+ if (sscanf(m->m_data, "%u%*[ ,]%u", &n1, &n2) == 2) {
+ HTONS(n1);
+ HTONS(n2);
+ /* n2 is the one on our host */
+ for (tmpso = slirp->tcb.so_next; tmpso != &slirp->tcb;
+ tmpso = tmpso->so_next) {
+ if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr &&
+ tmpso->so_lport == n2 &&
+ tmpso->so_faddr.s_addr == so->so_faddr.s_addr &&
+ tmpso->so_fport == n1) {
+ if (getsockname(tmpso->s, (struct sockaddr *)&addr,
+ &addrlen) == 0)
+ n2 = addr.sin_port;
+ break;
}
- NTOHS(n1);
- NTOHS(n2);
- so_rcv->sb_cc =
- snprintf(so_rcv->sb_data, so_rcv->sb_datalen,
- "%d,%d\r\n", n1, n2);
- so_rcv->sb_rptr = so_rcv->sb_data;
- so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
}
+ NTOHS(n1);
+ NTOHS(n2);
+ m_inc(m, snprintf(NULL, 0, "%d,%d\r\n", n1, n2) + 1);
+ m->m_len = snprintf(m->m_data, M_ROOM(m), "%d,%d\r\n", n1, n2);
+ assert(m->m_len < M_ROOM(m));
+ } else {
+ *eol = '\r';
}
- m_free(m);
- return 0;
+
+ return 1;
}
case EMU_FTP: /* ftp */
+ m_inc(m, m->m_len + 1);
*(m->m_data + m->m_len) = 0; /* NUL terminate for strstr */
if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) {
/*
@@ -771,6 +766,7 @@ int tcp_emu(struct socket *so, struct mbuf *m)
/*
* Need to emulate DCC CHAT, DCC SEND and DCC MOVE
*/
+ m_inc(m, m->m_len + 1);
*(m->m_data + m->m_len) = 0; /* NULL terminate the string for strstr */
if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL)
return 1;