svn commit: r185723 - head/sys/netgraph

Alexander Motin mav at FreeBSD.org
Sat Dec 6 15:00:49 PST 2008


Author: mav
Date: Sat Dec  6 23:00:48 2008
New Revision: 185723
URL: http://svn.freebsd.org/changeset/base/185723

Log:
  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.

Modified:
  head/sys/netgraph/ng_mppc.c

Modified: head/sys/netgraph/ng_mppc.c
==============================================================================
--- head/sys/netgraph/ng_mppc.c	Sat Dec  6 21:52:32 2008	(r185722)
+++ head/sys/netgraph/ng_mppc.c	Sat Dec  6 23:00:48 2008	(r185723)
@@ -492,17 +492,18 @@ ng_mppc_compress(node_p node, struct mbu
 		/* 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 mbu
 		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 mbu
 		/* 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 mbu
 			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) {


More information about the svn-src-all mailing list