Fix fragmentation also under FreeBSD and OS X

This PR addresses the remaining TCP fragmentation by piping the line buffered
internal print through cat, see also #1130.
It extends 1b52834 which was the same doing for Linux and
OpenBSD.

This PR also consolidates the last remaining low level socket calls
in client_simulation_sockets() into socksend_clienthello().

An negative performance effect is barely measurable.

It also does a check whether the fd 5 is taken by a tty as
I see this while writing the commit message ;-). We might
want to make that line better instead of just echoing. :-)
This commit is contained in:
Dirk 2018-10-11 21:00:33 +02:00
parent 2fb137dfcf
commit 2a27416fd7
1 changed files with 20 additions and 11 deletions

View File

@ -268,7 +268,7 @@ declare -r UA_SNEAKY="Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Fi
########### Initialization part, further global vars just being declared here ########### Initialization part, further global vars just being declared here
# #
PRINTF="" # which external printf to use PRINTF="" # which external printf to use. Empty presets the internal one, see #1130
IKNOW_FNAME=false IKNOW_FNAME=false
FIRST_FINDING=true # is this the first finding we are outputting to file? FIRST_FINDING=true # is this the first finding we are outputting to file?
JSONHEADER=true # include JSON headers and footers in HTML file, if one is being created JSONHEADER=true # include JSON headers and footers in HTML file, if one is being created
@ -4321,12 +4321,9 @@ client_simulation_sockets() {
fi fi
cipher_list_2send="$NW_STR" cipher_list_2send="$NW_STR"
debugme echo -e "\nsending client hello... "
code2network "${data}"
data="$NW_STR"
fd_socket 5 || return 6 fd_socket 5 || return 6
[[ "$DEBUG" -ge 4 ]] && echo && echo "\"$data\"" debugme echo -e "\nsending client hello... "
$PRINTF -- "$data" >&5 2>/dev/null & socksend_clienthello "${data}"
sleep $USLEEP_SND sleep $USLEEP_SND
sockread_serverhello 32768 sockread_serverhello 32768
@ -9167,6 +9164,7 @@ fd_socket() {
local proyxline="" local proyxline=""
local nodeip="$(tr -d '[]' <<< $NODEIP)" # sockets do not need the square brackets we have of IPv6 addresses local nodeip="$(tr -d '[]' <<< $NODEIP)" # sockets do not need the square brackets we have of IPv6 addresses
# we just need do it here, that's all! # we just need do it here, that's all!
[[ -t 5 ]] && echo "tty"
if [[ -n "$PROXY" ]]; then if [[ -n "$PROXY" ]]; then
# PROXYNODE works better than PROXYIP on modern versions of squid # PROXYNODE works better than PROXYIP on modern versions of squid
if ! exec 5<> /dev/tcp/${PROXYNODE}/${PROXYPORT}; then if ! exec 5<> /dev/tcp/${PROXYNODE}/${PROXYPORT}; then
@ -9288,7 +9286,12 @@ socksend_clienthello() {
code2network "$1" code2network "$1"
data="$NW_STR" data="$NW_STR"
[[ "$DEBUG" -ge 4 ]] && echo && echo "\"$data\"" [[ "$DEBUG" -ge 4 ]] && echo && echo "\"$data\""
$PRINTF -- "$data" >&5 2>/dev/null & if [[ -z "$PRINTF" ]] ;then
# We could also use "dd ibs=1M obs=1M" here but is seems to be at max 3% slower
printf -- "$data" | cat >&5 2>/dev/null &
else
$PRINTF -- "$data" 2>/dev/null >&5 2>/dev/null &
fi
sleep $USLEEP_SND sleep $USLEEP_SND
} }
@ -9305,7 +9308,11 @@ socksend() {
data="${data// /}" # strip ' ' data="${data// /}" # strip ' '
data="${data//,/\\}" # s&r , by \ data="${data//,/\\}" # s&r , by \
[[ $DEBUG -ge 4 ]] && echo && echo "\"$data\"" [[ $DEBUG -ge 4 ]] && echo && echo "\"$data\""
$PRINTF -- "$data" >&5 2>/dev/null & if [[ -z "$PRINTF" ]] ;then
printf -- "$data" | cat >&5 2>/dev/null &
else
$PRINTF -- "$data" 2>/dev/null >&5 2>/dev/null &
fi
sleep $2 sleep $2
} }
@ -15596,7 +15603,9 @@ check_bsd_mount() {
# The shell builtin printf flushes the write buffer at every \n, ("\x0a") which # The shell builtin printf flushes the write buffer at every \n, ("\x0a") which
# in turn means a new TCP fragment. That causes a slight performance penalty and # in turn means a new TCP fragment. That causes a slight performance penalty and
# and some F5s to hiccup, see #1113. Unfortunately this can be used only with GNU's # and some F5s to hiccup, see #1113. Unfortunately this can be used only with GNU's
# and OpenBSD's /usr/bin/printf -- FreeBSD + OS X can't do this. # and OpenBSD's /usr/bin/printf -- FreeBSD + OS X can't do this. Thus here we need
# to pipe through dd or cat, see socksend() and socksend_clienthello(). An empty
# $PRINTF signals the bash internal printf which then uses cat as a stdout buffer.
# A better solution needs to follow. # A better solution needs to follow.
# #
choose_printf() { choose_printf() {
@ -15605,14 +15614,14 @@ choose_printf() {
ptf="$(type -aP printf)" ptf="$(type -aP printf)"
if [[ -n "$ptf" ]]; then if [[ -n "$ptf" ]]; then
for p in $ptf; do for p in $ptf; do
if $p "\xc0\x14\xc0\xff\xee" | hexdump -C | grep -q 'c0 14 c0 ff ee'; then if $p "\xc0\x14\xc0\xff\xee" | hexdump -C | grep -q 'c0 14 c0 ff ee'; then
PRINTF=$p PRINTF=$p
return 0 return 0
fi fi
done done
fi fi
if type -t printf >/dev/null; then if type -t printf >/dev/null; then
PRINTF=printf PRINTF=""
return 0 return 0
fi fi
fatal "Neither external printf nor shell internal found. " $ERR_CLUELESS fatal "Neither external printf nor shell internal found. " $ERR_CLUELESS