diff --git a/tpws/helpers.c b/tpws/helpers.c index afdcc44..3ee8fd1 100644 --- a/tpws/helpers.c +++ b/tpws/helpers.c @@ -12,10 +12,6 @@ #include #include -#ifdef __linux__ -#include -#endif - #ifdef __ANDROID__ #include "andr/ifaddrs.h" #else @@ -23,6 +19,7 @@ #endif #include "helpers.h" +#include "linux_compat.h" int unique_size_t(size_t *pu, int ct) { @@ -481,7 +478,7 @@ void msleep(unsigned int ms) bool socket_supports_notsent() { int sfd; - struct tcp_info tcpi; + union my_tcp_info tcpi; sfd = socket(AF_INET,SOCK_STREAM,0); if (sfd<0) return false; @@ -494,22 +491,22 @@ bool socket_supports_notsent() } close(sfd); - return ts>=((char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi.tcpi_state + sizeof(tcpi.tcpi_notsent_bytes)); + return ts>=((char *)&tcpi.ti.tcpi_notsent_bytes - (char *)&tcpi.ti + sizeof(tcpi.ti.tcpi_notsent_bytes)); } bool socket_has_notsent(int sfd) { - struct tcp_info tcpi; + union my_tcp_info tcpi; socklen_t ts = sizeof(tcpi); if (getsockopt(sfd, IPPROTO_TCP, TCP_INFO, (char *)&tcpi, &ts) < 0) return false; - if (tcpi.tcpi_state != 1) // TCP_ESTABLISHED + if (tcpi.ti.tcpi_state != 1) // TCP_ESTABLISHED return false; - size_t s = (char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi + sizeof(tcpi.tcpi_notsent_bytes); + size_t s = (char *)&tcpi.ti.tcpi_notsent_bytes - (char *)&tcpi.ti + sizeof(tcpi.ti.tcpi_notsent_bytes); if (ts < s) // old structure version return false; - return !!tcpi.tcpi_notsent_bytes; + return !!tcpi.ti.tcpi_notsent_bytes; } bool socket_wait_notsent(int sfd, unsigned int delay_ms, unsigned int *wasted_ms) { diff --git a/tpws/linux_compat.h b/tpws/linux_compat.h new file mode 100644 index 0000000..e06114e --- /dev/null +++ b/tpws/linux_compat.h @@ -0,0 +1,105 @@ +#ifdef __linux__ + +#include + +// workaround for old headers + +struct tcp_info_new { + __u8 tcpi_state; + __u8 tcpi_ca_state; + __u8 tcpi_retransmits; + __u8 tcpi_probes; + __u8 tcpi_backoff; + __u8 tcpi_options; + __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; + __u8 tcpi_delivery_rate_app_limited : 1, tcpi_fastopen_client_fail : 2; + + __u32 tcpi_rto; + __u32 tcpi_ato; + __u32 tcpi_snd_mss; + __u32 tcpi_rcv_mss; + + __u32 tcpi_unacked; + __u32 tcpi_sacked; + __u32 tcpi_lost; + __u32 tcpi_retrans; + __u32 tcpi_fackets; + + /* Times. */ + __u32 tcpi_last_data_sent; + __u32 tcpi_last_ack_sent; /* Not remembered, sorry. */ + __u32 tcpi_last_data_recv; + __u32 tcpi_last_ack_recv; + + /* Metrics. */ + __u32 tcpi_pmtu; + __u32 tcpi_rcv_ssthresh; + __u32 tcpi_rtt; + __u32 tcpi_rttvar; + __u32 tcpi_snd_ssthresh; + __u32 tcpi_snd_cwnd; + __u32 tcpi_advmss; + __u32 tcpi_reordering; + + __u32 tcpi_rcv_rtt; + __u32 tcpi_rcv_space; + + __u32 tcpi_total_retrans; + + __u64 tcpi_pacing_rate; + __u64 tcpi_max_pacing_rate; + __u64 tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ + __u64 tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ + __u32 tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */ + __u32 tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */ + + __u32 tcpi_notsent_bytes; + __u32 tcpi_min_rtt; + __u32 tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */ + __u32 tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */ + + __u64 tcpi_delivery_rate; + + __u64 tcpi_busy_time; /* Time (usec) busy sending data */ + __u64 tcpi_rwnd_limited; /* Time (usec) limited by receive window */ + __u64 tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ + + __u32 tcpi_delivered; + __u32 tcpi_delivered_ce; + + __u64 tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */ + __u64 tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */ + __u32 tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */ + __u32 tcpi_reord_seen; /* reordering events seen */ + + __u32 tcpi_rcv_ooopack; /* Out-of-order packets received */ + + __u32 tcpi_snd_wnd; /* peer's advertised receive window after + * scaling (bytes) + */ + __u32 tcpi_rcv_wnd; /* local advertised receive window after + * scaling (bytes) + */ + + __u32 tcpi_rehash; /* PLB or timeout triggered rehash attempts */ + + __u16 tcpi_total_rto; /* Total number of RTO timeouts, including + * SYN/SYN-ACK and recurring timeouts. + */ + __u16 tcpi_total_rto_recoveries; /* Total number of RTO + * recoveries, including any + * unfinished recovery. + */ + __u32 tcpi_total_rto_time; /* Total time spent in RTO recoveries + * in milliseconds, including any + * unfinished recovery. + */ +}; + +union my_tcp_info +{ + struct tcp_info ti_native; + struct tcp_info_new ti; +}; + +#endif diff --git a/tpws/params.h b/tpws/params.h index 52022d8..67a357b 100644 --- a/tpws/params.h +++ b/tpws/params.h @@ -18,7 +18,7 @@ #define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3 #define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60 -#define FIX_SEG_DEFAULT_MAX_WAIT 30 +#define FIX_SEG_DEFAULT_MAX_WAIT 50 enum bindll { unwanted=0, no, prefer, force };