>iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS
>--set-mss 1350 если не добавлять это правило, то соединения с некоторыми серверами не устанавливаются вообще, например с mail.ru
с этим правилом соединения устанавливаются но сообщение "anon log[decaps_gre:pptp_gre.c:407]: buffering packet 5636 (expecting 5632, lost or reordered)
" все равно сыпятся и заметно меньше скорость соединений, замерял на speedtest.net на винде pptp-соединение в 10 раз быстрее чем на linux (
вот исходники этой части в pptp, может что-то здесь можно поправить...
decaps_gre:pptp_gre.c
/*** decaps_gre ***************************************************************/
int decaps_gre (int fd, callback_t callback, int cl)
{
unsigned char buffer[PACKET_MAX + 64 /*ip header*/];
struct pptp_gre_header *header;
int status, ip_len = 0;
static int first = 1;
unsigned int headersize;
unsigned int payload_len;
u_int32_t seq;
if ((status = read (fd, buffer, sizeof(buffer))) <= 0) {
warn("short read (%d): %s", status, strerror(errno));
stats.rx_errors++;
return -1;
}
/* strip off IP header, if present */
if ((buffer[0] & 0xF0) == 0x40)
ip_len = (buffer[0] & 0xF) * 4;
header = (struct pptp_gre_header *)(buffer + ip_len);
/* verify packet (else discard) */
if ( /* version should be 1 */
((ntoh8(header->ver) & 0x7F) != PPTP_GRE_VER) ||
/* PPTP-GRE protocol for PPTP */
(ntoh16(header->protocol) != PPTP_GRE_PROTO)||
/* flag C should be clear */
PPTP_GRE_IS_C(ntoh8(header->flags)) ||
/* flag R should be clear */
PPTP_GRE_IS_R(ntoh8(header->flags)) ||
/* flag K should be set */
(!PPTP_GRE_IS_K(ntoh8(header->flags))) ||
/* routing and recursion ctrl = 0 */
((ntoh8(header->flags)&0xF) != 0)) {
/* if invalid, discard this packet */
warn("Discarding GRE: %X %X %X %X %X %X",
ntoh8(header->ver)&0x7F, ntoh16(header->protocol),
PPTP_GRE_IS_C(ntoh8(header->flags)),
PPTP_GRE_IS_R(ntoh8(header->flags)),
PPTP_GRE_IS_K(ntoh8(header->flags)),
ntoh8(header->flags) & 0xF);
stats.rx_invalid++;
return 0;
}
/* silently discard packets not for this call */
if (ntoh16(header->call_id) != pptp_gre_call_id) return 0;
/* test if acknowledgement present */
if (PPTP_GRE_IS_A(ntoh8(header->ver))) {
u_int32_t ack = (PPTP_GRE_IS_S(ntoh8(header->flags)))?
header->ack:header->seq; /* ack in different place if S = 0 */
ack = ntoh32( ack);
if (ack > ack_recv) ack_recv = ack;
/* also handle sequence number wrap-around */
if (WRAPPED(ack,ack_recv)) ack_recv = ack;
if (ack_recv == stats.pt.seq) {
int rtt = time_now_usecs() - stats.pt.time;
stats.rtt = (stats.rtt + rtt) / 2;
}
}
/* test if payload present */
if (!PPTP_GRE_IS_S(ntoh8(header->flags)))
return 0; /* ack, but no payload */
headersize = sizeof(*header);
payload_len = ntoh16(header->payload_len);
seq = ntoh32(header->seq);
/* no ack present? */
if (!PPTP_GRE_IS_A(ntoh8(header->ver))) headersize -= sizeof(header->ack);
/* check for incomplete packet (length smaller than expected) */
if (status - headersize < payload_len) {
warn("discarding truncated packet (expected %d, got %d bytes)",
payload_len, status - headersize);
stats.rx_truncated++;
return 0;
}
/* check for expected sequence number */
if ( first || (seq == seq_recv + 1)) { /* wrap-around safe */
if ( log_level >= 2 )
log("accepting packet %d", seq);
stats.rx_accepted++;
first = 0;
seq_recv = seq;
return callback(cl, buffer + ip_len + headersize, payload_len);
/* out of order, check if the number is too low and discard the packet.
* (handle sequence number wrap-around, and try to do it right) */
} else if ( seq < seq_recv + 1 || WRAPPED(seq_recv, seq) ) {
if ( log_level >= 1 )
log("discarding duplicate or old packet %d (expecting %d)",
seq, seq_recv + 1);
stats.rx_underwin++;
/* sequence number too high, is it reasonably close? */
} else if ( seq < seq_recv + MISSING_WINDOW ||
WRAPPED(seq, seq_recv + MISSING_WINDOW) ) {
stats.rx_buffered++;
if ( log_level >= 1 )
log("%s packet %d (expecting %d, lost or reordered)",
disable_buffer ? "accepting" : "buffering",
seq, seq_recv+1);
if ( disable_buffer ) {
seq_recv = seq;
stats.rx_lost += seq - seq_recv - 1;
return callback(cl, buffer + ip_len + headersize, payload_len);
} else {
pqueue_add(seq, buffer + ip_len + headersize, payload_len);
}
/* no, packet must be discarded */
} else {
if ( log_level >= 1 )
warn("discarding bogus packet %d (expecting %d)",
seq, seq_recv + 1);
stats.rx_overwin++;
}
return 0;
}