•  desabrochar luz

TCSplitter

Um túnel para dividir a conexão TCP ou UDP em várias conexões TCP

Meta

Quando você deseja dividir uma conexão TCP em várias? Normalmente você usa um túnel alcançar o oposto exato . Meu caso de uso foi contornar as limitações de largura de banda em uma rede móvel, então os testes foram realizados com um cartão SIM sem mais dados deixados em seu plano[1].

Como funciona

o túnel foi escrito em Golang uma vez que é rápido o suficiente e comumente usado para ferramentas de rede. O cli quase não pode ser usado, pois a maioria das opções foi reformulada enquanto eu testava métodos diferentes.

Inicialmente havia "flings" e "lassos", para dividir o número de conexões de saída (arremessada) e de entrada (laçada), mas isso foi uma abstração desnecessária, pois é melhor marcar pacotes com seu destino, embora a intenção principal fosse para oferecer limites de taxa diferentes para conexões de saída e de entrada, de modo que uma separação de nível mais alto entre para cima / para baixo parecia prática.

O cliente deve instanciar todas as conexões, uma vez que assumimos que o servidor não pode abrir conexões de saída. Quando os clientes recebem uma conexão de um aplicativo do usuário, ele configura o pool necessário de conexões com o servidor e, quaisquer dados que recebe, ele os divide entre as conexões dedicadas, de acordo com um limite definido pelo usuário.

Os pacotes são então enviados ao servidor, que deve reconstruí-los na ordem correta, porque diferentes conexões TCP podem terminar o fluxo de dados a qualquer momento (a ordem de envio não é respeitada, porque roteamento ) e, em seguida, encaminhado para o aplicativo receptor.

As conexões são fechadas e novas abertas conforme o limite de dados configurado por conexão é atingido, semelhante a como sombrasproxies túneis de dados em diferentes fluxos com o objetivo de mascarar o comportamento dos fluxos de dados, exceto que nosso túnel está fazendo isso com a maior freqüência possível.

Porque funciona

A intenção aqui é controlar a quantidade de dados que cada conexão deve tratar. Para nossos propósitos, nunca foi além, geralmente é o MTU tamanho da janela. Você pode pensar no MTU como o limite superior de uma parte dos dados que passam por toda a rede, e era nosso alvo porque queríamos contornar os limites da taxa de largura de banda de uma rede com portas. Para limitar a quantidade de dados pelos quais um cliente pode passar, você precisa contar isso, certo? Se sua lógica funciona com algo como umdo-while

Então você precisa pelo menos receber umpacket . Não tenho certeza se é isso que realmente acontece ou se o motivo do meu túnel funcionar é outro. Talvez seja totalmente possível verificar até mesmo o primeiro pacote, mas de uma perspectiva de design, isso significaria que você teria que verificar cada conexão única, o que tornaria o sistema mais fraco para ataques DOS e, sim, meu túnel poderia ser facilmente usado como uma ferramenta DOS / Stress eficiente, já que você pode dividir os dados em pacotes muito pequenos (o que significa que as conexões TCP terão uma alta pressão de reciclagem ) e tenha um conjunto de conexões do tamanho de sua preferência.

Testes em portas diferentes também mostraram que só era possível durante algum portas, e que o limite era constantemente diferente entre as portas, com443 dando uma das janelas mais altas, ao redor20kb , supondo porqueTLS os apertos de mão requerem mais dados, e que esses limites de taxa mudariam com base na hora do dia[2].

Resultados

Tentei apagar a codificação na esperança de aumentar a taxa de transferência de dados. Usando uma biblioteca de codificação de eliminação e codificando / decodificando os próprios dados, e também sobrepondo o KCP protocolo sobre o meu protocolo de divisão. Experimentar o KCP pode parecer uma abordagem para trás, uma vez que troca melhor latência por menor rendimento, mas minha suposição inicial era que meu gargalo estava nas conexões perdidas no meio da transmissão, o que causaria muitos pacotes corrompidos, então eu poderia ter alcançado um maior rendimento com correção de erros.

Acontece que era apenas um limite de taxa sobre quantas conexões TCP um cliente pode enviar pela rede, portanto, apenas uma proteção DOS sobre a qual não posso fazer nada. Após X quantidades de conexões, qualquerSYN as tentativas param de receber o devidoACK , preenchendo o acúmulo e, eventualmente, fazendo o túnel parar. Tentativa e erro mostraram que era possível entre4-8[3] conexões abertas a qualquer momento, e com um MTU de500-1000 bytes você poderia manter um fluxo constante em torno de pelo menos128kbps , se um fluxo constante não fosse um requisito, você poderia alcançar velocidades mais altas em um período de tempo mais curto estourando muitas conexões sob demanda.

Em contraste, um (verdadeiro)DNS túnel mal consegue empurrar56kbps e pode ser rapidamente limitado porque acho que um grande número de solicitações de DNS parece mais suspeito do que solicitações de TCP. Temos que especificar que umtrue O túnel DNS codifica dados (de saída) em subdomínios falsos e decodifica os dados (de entrada) recebidos por meio de consultas de registros DNS, enquanto às vezes um túnel DNS pode ser considerado uma conexão UDP bruta pela porta DNS, que provavelmente em algum momento no passado, servidores DNS permitido e encaminhado corretamente.

Conclusões

Não tenho certeza se alcancei meu objetivo Utilitário sábio, já que executar esse tipo de túnel pode fazer seu telefone esquentar bastante e desperdiçar muita bateria, mas tê-lo como uma conexão de backup pode ser reconfortante ... se eu realmente me preocupasse em torná-lo estável o suficiente :)

[1]normalmente, quando um cartão SIM não tem mais dados para navegar na web, as solicitações da web redirecionam para o gateway de captura (para dizer a você para comprar mais dados)
[2]planos de dados móveis podem fornecer uma conexão melhor durante a noite
[3]Este número, um tanto alinhado com as contagens de núcleo comuns, pode induzir você a suspeitar que o kernel está limitando as conexões de alguma forma, o cenário de conexões abertas do nosso túnel é definitivamente incomum, mas o ajuste dos botões do Linux nunca deu melhores resultados do meu lado.

Tags de postagem: