aboutsummaryrefslogtreecommitdiff
path: root/sys/netgraph/ng_mppc.c
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2008-12-06 23:00:48 +0000
committerAlexander Motin <mav@FreeBSD.org>2008-12-06 23:00:48 +0000
commit11d1cade739439af020f7dfeefef0ef09af2230c (patch)
treea345b547c6063fb235f59c6bd6f118381261153f /sys/netgraph/ng_mppc.c
parentd493985afd97ef2fab60f8d924bf8d8cf8b29d35 (diff)
downloadsrc-11d1cade739439af020f7dfeefef0ef09af2230c.tar.gz
src-11d1cade739439af020f7dfeefef0ef09af2230c.zip
Carefully handle memory errors to keep peers compression/encryption state
consistent. There are some cases reported where peers fatally getting out of sync without any visible reason. I hope this solve the problem.
Notes
Notes: svn path=/head/; revision=185723
Diffstat (limited to 'sys/netgraph/ng_mppc.c')
-rw-r--r--sys/netgraph/ng_mppc.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c
index 2e9d932d4c04..472968f8d82c 100644
--- a/sys/netgraph/ng_mppc.c
+++ b/sys/netgraph/ng_mppc.c
@@ -492,17 +492,18 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
/* Work with contiguous regions of memory. */
inlen = m->m_pkthdr.len;
inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
- if (inbuf == NULL) {
- m_freem(m);
- return (ENOMEM);
- }
+ if (inbuf == NULL)
+ goto err1;
m_copydata(m, 0, inlen, (caddr_t)inbuf);
outlen = MPPC_MAX_BLOWUP(inlen);
outbuf = malloc(outlen, M_NETGRAPH_MPPC, M_NOWAIT);
if (outbuf == NULL) {
- m_freem(m);
free(inbuf, M_NETGRAPH_MPPC);
+err1:
+ m_freem(m);
+ MPPC_InitCompressionHistory(d->history);
+ d->flushed = 1;
return (ENOMEM);
}
@@ -538,8 +539,13 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
free(outbuf, M_NETGRAPH_MPPC);
/* Check m_devget() result. */
- if (m == NULL)
+ if (m == NULL) {
+ if (!d->flushed) {
+ MPPC_InitCompressionHistory(d->history);
+ d->flushed = 1;
+ }
return (ENOMEM);
+ }
}
#endif
@@ -551,6 +557,18 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
/* Set header bits */
header |= MPPC_FLAG_ENCRYPTED;
+ /* We must own the mbuf chain exclusively to modify it. */
+ m = m_unshare(m, M_DONTWAIT);
+ if (m == NULL) {
+ if (!d->flushed) {
+#ifdef NETGRAPH_MPPC_COMPRESSION
+ MPPC_InitCompressionHistory(d->history);
+#endif
+ d->flushed = 1;
+ }
+ return (ENOMEM);
+ }
+
/* Update key if it's time */
if ((d->cfg.bits & MPPE_STATELESS) != 0
|| (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) {
@@ -562,11 +580,6 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
rc4_init(&d->rc4, d->key, KEYLEN(d->cfg.bits));
}
- /* We must own the mbuf chain exclusively to modify it. */
- m = m_unshare(m, M_DONTWAIT);
- if (m == NULL)
- return (ENOMEM);
-
/* Encrypt packet */
m1 = m;
while (m1) {