* Append the data in mbuf chain (m) into the socket buffer sb following mbuf * (n). If (n) is NULL, the buffer is presumed empty. * * When the data is compressed, mbufs in the chain may be handled in one of * three ways: * * (1) The mbuf may simply be dropped, if it contributes nothing (no data, no * record boundary, and no change in data type). * * (2) The mbuf may be coalesced -- i
| 1302 | * end-of-record. |
| 1303 | */ |
| 1304 | void |
| 1305 | sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n) |
| 1306 | { |
| 1307 | int eor = 0; |
| 1308 | struct mbuf *o; |
| 1309 | |
| 1310 | SOCKBUF_LOCK_ASSERT(sb); |
| 1311 | |
| 1312 | while (m) { |
| 1313 | eor |= m->m_flags & M_EOR; |
| 1314 | if (m->m_len == 0 && |
| 1315 | (eor == 0 || |
| 1316 | (((o = m->m_next) || (o = n)) && |
| 1317 | o->m_type == m->m_type))) { |
| 1318 | if (sb->sb_lastrecord == m) |
| 1319 | sb->sb_lastrecord = m->m_next; |
| 1320 | m = m_free(m); |
| 1321 | continue; |
| 1322 | } |
| 1323 | if (n && (n->m_flags & M_EOR) == 0 && |
| 1324 | M_WRITABLE(n) && |
| 1325 | ((sb->sb_flags & SB_NOCOALESCE) == 0) && |
| 1326 | !(m->m_flags & M_NOTREADY) && |
| 1327 | !(n->m_flags & (M_NOTREADY | M_EXTPG)) && |
| 1328 | !mbuf_has_tls_session(m) && |
| 1329 | !mbuf_has_tls_session(n) && |
| 1330 | m->m_len <= MCLBYTES / 4 && /* XXX: Don't copy too much */ |
| 1331 | m->m_len <= M_TRAILINGSPACE(n) && |
| 1332 | n->m_type == m->m_type) { |
| 1333 | m_copydata(m, 0, m->m_len, mtodo(n, n->m_len)); |
| 1334 | n->m_len += m->m_len; |
| 1335 | sb->sb_ccc += m->m_len; |
| 1336 | if (sb->sb_fnrdy == NULL) |
| 1337 | sb->sb_acc += m->m_len; |
| 1338 | if (m->m_type != MT_DATA && m->m_type != MT_OOBDATA) |
| 1339 | /* XXX: Probably don't need.*/ |
| 1340 | sb->sb_ctl += m->m_len; |
| 1341 | m = m_free(m); |
| 1342 | continue; |
| 1343 | } |
| 1344 | if (m->m_len <= MLEN && (m->m_flags & M_EXTPG) && |
| 1345 | (m->m_flags & M_NOTREADY) == 0 && |
| 1346 | !mbuf_has_tls_session(m)) |
| 1347 | (void)mb_unmapped_compress(m); |
| 1348 | if (n) |
| 1349 | n->m_next = m; |
| 1350 | else |
| 1351 | sb->sb_mb = m; |
| 1352 | sb->sb_mbtail = m; |
| 1353 | sballoc(sb, m); |
| 1354 | n = m; |
| 1355 | m->m_flags &= ~M_EOR; |
| 1356 | m = m->m_next; |
| 1357 | n->m_next = 0; |
| 1358 | } |
| 1359 | if (eor) { |
| 1360 | KASSERT(n != NULL, ("sbcompress: eor && n == NULL")); |
| 1361 | n->m_flags |= eor; |
no test coverage detected