4646
4747#include "mstats.h"
4848
49+ #include <sys/select.h>
50+ #include <sys/time.h>
51+
4952counter_type link_read_bytes_global ; /* GLOBAL */
5053counter_type link_write_bytes_global ; /* GLOBAL */
5154
@@ -78,6 +81,15 @@ show_wait_status(struct context *c)
7881
7982#endif /* ifdef ENABLE_DEBUG */
8083
84+ bool check_bulk_mode (struct context * c )
85+ {
86+ if ((c -> c2 .frame .bulk_size > 0 ) && (c -> c1 .tuntap != NULL ) && (c -> c2 .buffers != NULL ))
87+ {
88+ return true;
89+ }
90+ return false;
91+ }
92+
8193static void
8294check_tls_errors_co (struct context * c )
8395{
@@ -605,6 +617,21 @@ buffer_turnover(const uint8_t *orig_buf, struct buffer *dest_stub, struct buffer
605617 }
606618}
607619
620+ uint8_t * buff_prepsize (uint8_t * buff , int * size )
621+ {
622+ buff [0 ] = ((* size >> 8 ) & 0xff );
623+ buff [1 ] = ((* size >> 0 ) & 0xff );
624+ buff += 2 ;
625+ return buff ;
626+ }
627+
628+ uint8_t * buff_postsize (uint8_t * buff , int * size )
629+ {
630+ * size = ((buff [0 ] << 8 ) + (buff [1 ] << 0 ));
631+ buff += 2 ;
632+ return buff ;
633+ }
634+
608635/*
609636 * Compress, fragment, encrypt and HMAC-sign an outgoing packet.
610637 * Input: c->c2.buf
@@ -1031,6 +1058,7 @@ process_incoming_link_part1(struct context *c, struct link_socket_info *lsi, boo
10311058 fprintf (stderr , "R" );
10321059 }
10331060#endif
1061+
10341062 msg (D_LINK_RW , "%s READ [%d] from %s: %s" , proto2ascii (lsi -> proto , lsi -> af , true),
10351063 BLEN (& c -> c2 .buf ), print_link_socket_actual (& c -> c2 .from , & gc ), PROTO_DUMP (& c -> c2 .buf , & gc ));
10361064
@@ -1211,6 +1239,26 @@ process_incoming_link_part2(struct context *c, struct link_socket_info *lsi,
12111239 }
12121240}
12131241
1242+ void process_incoming_link_part3 (struct context * c )
1243+ {
1244+ int leng = BLEN (& c -> c2 .buf );
1245+ if (leng > 0 )
1246+ {
1247+ if (check_bulk_mode (c ))
1248+ {
1249+ c -> c2 .buffers -> send_tun_max .offset = TUN_BAT_OFF ;
1250+ c -> c2 .buffers -> send_tun_max .len = leng ;
1251+ bcopy (BPTR (& c -> c2 .buf ), BPTR (& c -> c2 .buffers -> send_tun_max ), leng );
1252+ c -> c2 .to_tun .offset += 2 ;
1253+ c -> c2 .buf .offset += 2 ;
1254+ }
1255+ }
1256+ else
1257+ {
1258+ buf_reset (& c -> c2 .to_tun );
1259+ }
1260+ }
1261+
12141262static void
12151263process_incoming_link (struct context * c , struct link_socket * sock )
12161264{
@@ -1221,6 +1269,7 @@ process_incoming_link(struct context *c, struct link_socket *sock)
12211269
12221270 process_incoming_link_part1 (c , lsi , false);
12231271 process_incoming_link_part2 (c , lsi , orig_buf );
1272+ process_incoming_link_part3 (c );
12241273
12251274 perf_pop ();
12261275}
@@ -1321,7 +1370,7 @@ process_incoming_dco(struct context *c)
13211370 */
13221371
13231372void
1324- read_incoming_tun (struct context * c )
1373+ read_incoming_tun_part2 (struct context * c )
13251374{
13261375 /*
13271376 * Setup for read() call on TUN/TAP device.
@@ -1382,6 +1431,54 @@ read_incoming_tun(struct context *c)
13821431 perf_pop ();
13831432}
13841433
1434+ void read_incoming_tun_part3 (struct context * c )
1435+ {
1436+ fd_set rfds ;
1437+ struct timeval timo ;
1438+ if (check_bulk_mode (c ))
1439+ {
1440+ int plen = 0 , pidx = -1 ;
1441+ int fdno = c -> c1 .tuntap -> fd ;
1442+ for (int x = 0 ; x < TUN_BAT_MAX ; ++ x )
1443+ {
1444+ int leng = plen , indx = (pidx + 1 );
1445+ if (indx >= TUN_BAT_MIN ) { break ; }
1446+ if (leng < 1 )
1447+ {
1448+ FD_ZERO (& rfds );
1449+ FD_SET (fdno , & rfds );
1450+ timo .tv_sec = 0 ;
1451+ timo .tv_usec = 0 ;
1452+ select (fdno + 1 , & rfds , NULL , NULL , & timo );
1453+ if (FD_ISSET (fdno , & rfds ))
1454+ {
1455+ read_incoming_tun_part2 (c );
1456+ plen = BLEN (& c -> c2 .buf );
1457+ } else { break ; }
1458+ }
1459+ leng = plen ;
1460+ if (leng > 0 )
1461+ {
1462+ c -> c2 .buffers -> read_tun_bufs [indx ].offset = TUN_BAT_OFF ;
1463+ c -> c2 .buffers -> read_tun_bufs [indx ].len = leng ;
1464+ bcopy (BPTR (& c -> c2 .buf ), BPTR (& c -> c2 .buffers -> read_tun_bufs [indx ]), leng );
1465+ c -> c2 .bufs [indx ] = c -> c2 .buffers -> read_tun_bufs [indx ];
1466+ pidx = indx ;
1467+ } else { break ; }
1468+ plen = 0 ;
1469+ }
1470+ c -> c2 .buffers -> bulk_indx = pidx ;
1471+ }
1472+ }
1473+
1474+ void read_incoming_tun (struct context * c )
1475+ {
1476+ if (c -> c2 .frame .bulk_size <= 0 ) {
1477+ read_incoming_tun_part2 (c );
1478+ }
1479+ read_incoming_tun_part3 (c );
1480+ }
1481+
13851482/**
13861483 * Drops UDP packets which OS decided to route via tun.
13871484 *
@@ -1469,7 +1566,7 @@ drop_if_recursive_routing(struct context *c, struct buffer *buf)
14691566 */
14701567
14711568void
1472- process_incoming_tun (struct context * c , struct link_socket * out_sock )
1569+ process_incoming_tun_part2 (struct context * c , struct link_socket * out_sock )
14731570{
14741571 struct gc_arena gc = gc_new ();
14751572
@@ -1488,7 +1585,7 @@ process_incoming_tun(struct context *c, struct link_socket *out_sock)
14881585#endif
14891586
14901587 /* Show packet content */
1491- dmsg (D_TUN_RW , "TUN READ [%d]" , BLEN (& c -> c2 .buf ));
1588+ dmsg (D_TUN_RW , "TUN READ [%d] [%d] " , BLEN (& c -> c2 .buf ), c -> c2 . frame . buf . payload_size );
14921589
14931590 if (c -> c2 .buf .len > 0 )
14941591 {
@@ -1512,7 +1609,9 @@ process_incoming_tun(struct context *c, struct link_socket *out_sock)
15121609 }
15131610 if (c -> c2 .buf .len > 0 )
15141611 {
1612+ if ((c -> c2 .buffers == NULL ) || (c -> c2 .buffers -> bulk_flag != -2 )) {
15151613 encrypt_sign (c , true);
1614+ }
15161615 }
15171616 else
15181617 {
@@ -1522,6 +1621,65 @@ process_incoming_tun(struct context *c, struct link_socket *out_sock)
15221621 gc_free (& gc );
15231622}
15241623
1624+ void process_incoming_tun_part3 (struct context * c , struct link_socket * out_sock )
1625+ {
1626+ if (c -> c2 .buf .len > 0 )
1627+ {
1628+ if (check_bulk_mode (c ))
1629+ {
1630+ c -> c2 .buffers -> bulk_flag = -2 ;
1631+ c -> c2 .buffers -> read_tun_max .offset = TUN_BAT_OFF ;
1632+ c -> c2 .buffers -> read_tun_max .len = 0 ;
1633+ uint8_t * temp = BPTR (& c -> c2 .buffers -> read_tun_max );
1634+ int plen = 0 , fdno = c -> c1 .tuntap -> fd ;
1635+ int maxl = 0 , leng = (c -> c2 .buffers -> bulk_indx + 1 );
1636+ if ((fdno > 0 ) && (leng > 0 ))
1637+ {
1638+ for (int x = 0 ; x < leng ; ++ x )
1639+ {
1640+ c -> c2 .buf = c -> c2 .bufs [x ];
1641+ process_incoming_tun_part2 (c , out_sock );
1642+ if (BLEN (& c -> c2 .buf ) < 1 )
1643+ {
1644+ c -> c2 .bufs [x ].len = 0 ;
1645+ }
1646+ }
1647+ for (int x = 0 ; x < leng ; ++ x )
1648+ {
1649+ plen = c -> c2 .bufs [x ].len ;
1650+ if (plen > 0 )
1651+ {
1652+ temp = buff_prepsize (temp , & plen );
1653+ bcopy (BPTR (& c -> c2 .bufs [x ]), temp , plen );
1654+ temp += plen ; maxl += (plen + 2 );
1655+ }
1656+ }
1657+ if (maxl > 0 )
1658+ {
1659+ c -> c2 .buffers -> read_tun_max .offset = TUN_BAT_OFF ;
1660+ c -> c2 .buffers -> read_tun_max .len = maxl ;
1661+ c -> c2 .buf = c -> c2 .buffers -> read_tun_max ;
1662+ encrypt_sign (c , true);
1663+ }
1664+ }
1665+ c -> c2 .buffers -> bulk_indx = -1 ;
1666+ c -> c2 .buffers -> bulk_flag = -1 ;
1667+ }
1668+ }
1669+ else
1670+ {
1671+ buf_reset (& c -> c2 .to_link );
1672+ }
1673+ }
1674+
1675+ void process_incoming_tun (struct context * c , struct link_socket * out_sock )
1676+ {
1677+ if (c -> c2 .frame .bulk_size <= 0 ) {
1678+ process_incoming_tun_part2 (c , out_sock );
1679+ }
1680+ process_incoming_tun_part3 (c , out_sock );
1681+ }
1682+
15251683/**
15261684 * Forges a IPv6 ICMP packet with a no route to host error code from the
15271685 * IPv6 packet in buf and sends it directly back to the client via the tun
@@ -1748,7 +1906,7 @@ process_outgoing_link(struct context *c, struct link_socket *sock)
17481906
17491907 perf_push (PERF_PROC_OUT_LINK );
17501908
1751- if (c -> c2 .to_link .len > 0 && c -> c2 .to_link .len <= c -> c2 .frame .buf .payload_size )
1909+ if (c -> c2 .to_link .len > 0 && ( c -> c2 .to_link .len <= c -> c2 .frame .buf .payload_size || c -> c2 . frame . bulk_size > 0 ) )
17521910 {
17531911 /*
17541912 * Setup for call to send/sendto which will send
@@ -1793,6 +1951,7 @@ process_outgoing_link(struct context *c, struct link_socket *sock)
17931951 fprintf (stderr , "W" );
17941952 }
17951953#endif
1954+
17961955 msg (D_LINK_RW , "%s WRITE [%d] to %s: %s" ,
17971956 proto2ascii (sock -> info .proto , sock -> info .af , true), BLEN (& c -> c2 .to_link ),
17981957 print_link_socket_actual (c -> c2 .to_link_addr , & gc ), PROTO_DUMP (& c -> c2 .to_link , & gc ));
@@ -1892,7 +2051,7 @@ process_outgoing_link(struct context *c, struct link_socket *sock)
18922051 */
18932052
18942053void
1895- process_outgoing_tun (struct context * c , struct link_socket * in_sock )
2054+ process_outgoing_tun_part2 (struct context * c , struct link_socket * in_sock )
18962055{
18972056 /*
18982057 * Set up for write() call to TUN/TAP
@@ -1912,7 +2071,7 @@ process_outgoing_tun(struct context *c, struct link_socket *in_sock)
19122071 process_ip_header (c , PIP_MSSFIX | PIPV4_EXTRACT_DHCP_ROUTER | PIPV4_CLIENT_NAT | PIP_OUTGOING ,
19132072 & c -> c2 .to_tun , in_sock );
19142073
1915- if (c -> c2 .to_tun .len <= c -> c2 .frame .buf .payload_size )
2074+ if (c -> c2 .to_tun .len <= c -> c2 .frame .buf .payload_size || c -> c2 . frame . bulk_size > 0 )
19162075 {
19172076 /*
19182077 * Write to TUN/TAP device.
@@ -1925,7 +2084,8 @@ process_outgoing_tun(struct context *c, struct link_socket *in_sock)
19252084 fprintf (stderr , "w" );
19262085 }
19272086#endif
1928- dmsg (D_TUN_RW , "TUN WRITE [%d]" , BLEN (& c -> c2 .to_tun ));
2087+
2088+ dmsg (D_TUN_RW , "TUN WRITE [%d] [%d]" , BLEN (& c -> c2 .to_tun ), c -> c2 .frame .buf .payload_size );
19292089
19302090#ifdef PACKET_TRUNCATION_CHECK
19312091 ipv4_packet_size_verify (BPTR (& c -> c2 .to_tun ), BLEN (& c -> c2 .to_tun ), TUNNEL_TYPE (c -> c1 .tuntap ),
@@ -1981,6 +2141,38 @@ process_outgoing_tun(struct context *c, struct link_socket *in_sock)
19812141 perf_pop ();
19822142}
19832143
2144+ void process_outgoing_tun_part3 (struct context * c , struct link_socket * in_sock )
2145+ {
2146+ if (check_bulk_mode (c ))
2147+ {
2148+ int maxl = 0 , plen = 0 ;
2149+ int leng = BLEN (& c -> c2 .buffers -> send_tun_max );
2150+ uint8_t * temp = BPTR (& c -> c2 .buffers -> send_tun_max );
2151+ for (int x = 0 ; x < TUN_BAT_MAX ; ++ x )
2152+ {
2153+ temp = buff_postsize (temp , & plen );
2154+ if ((leng > 0 ) && (plen > 0 ) && ((maxl + plen ) < leng ))
2155+ {
2156+ c -> c2 .to_tun = c -> c2 .buffers -> to_tun_max ;
2157+ c -> c2 .to_tun .offset = TUN_BAT_OFF ;
2158+ c -> c2 .to_tun .len = plen ;
2159+ bcopy (temp , BPTR (& c -> c2 .to_tun ), plen );
2160+ temp += plen ; maxl += (plen + 2 );
2161+ process_outgoing_tun_part2 (c , in_sock );
2162+ } else { break ; }
2163+ }
2164+ }
2165+ buf_reset (& c -> c2 .to_tun );
2166+ }
2167+
2168+ void process_outgoing_tun (struct context * c , struct link_socket * in_sock )
2169+ {
2170+ if (c -> c2 .frame .bulk_size <= 0 ) {
2171+ process_outgoing_tun_part2 (c , in_sock );
2172+ }
2173+ process_outgoing_tun_part3 (c , in_sock );
2174+ }
2175+
19842176void
19852177pre_select (struct context * c )
19862178{
0 commit comments