Qual é o caminho de remontagem de uma resposta HTTP?

0

Estou tentando entender como os sistemas operacionais geralmente implementam a remontagem de solicitações de rede. Da minha melhor compreensão, o seguinte é verdadeiro:

Uma solicitação HTTP é feita na camada de aplicativo usando alguma biblioteca HTTP. Esta biblioteca HTTP é realmente um wrapper para alguma implementação de socket pelo SO.

Um soquete "transmissor" é instanciado usando o destino e a origem da solicitação HTTP.

Um soquete "receptor" é instanciado usando o endereço IP do dispositivo e uma porta aleatória (livre).

A mensagem HTTP é "enviada" usando o descritor de arquivo do soquete "transmissor".

O método "send" do socket envia a mensagem para a implementação TCP do SO.

A implementação TCP segmenta a mensagem HTTP, prefixando a porta de destino (fornecida ao instanciar o soquete) e a porta de origem. (Eu suponho que isso é de alguma forma passado dependendo da implementação.) Uma vez que a mensagem HTTP foi segmentada e os cabeçalhos TCP anexados a ela, os segmentos TCP são então passados para a implementação IP do sistema operacional.

Os segmentos TCP são prefixados com cabeçalhos IP. O endereço de destino IP foi fornecido ao instanciar o soquete. (Novamente eu suponho que o endereço IP de origem é passado dependendo da implementação).

Os pacotes IP são então encapsulados com cabeçalhos Ethernet, enviados ao roteador, enviados ao servidor, o servidor processa a solicitação e envia a resposta.

É aqui que o meu entendimento divide o que exatamente acontece no processo de remontagem.

Como a resposta retorna ao buffer de recebimento do soquete "receptor", mais uma vez que o pacote IP retorna ao dispositivo?

Obviamente, os cabeçalhos caem, mas quais são as etapas para recuperá-lo especificamente para o buffer de recebimento do soquete "receptor" e, em seguida, do soquete de volta para o Aplicativo?

PS Eu estou esperando por mais detalhes de implementação técnica do que apenas "IP remonta-o" ou "TCP remonta-o" e passa para a próxima camada. Espero entender exatamente como isso ocorre, em vez de apenas teoricamente (embora eu entenda que é específico do sistema operacional).

Editar:

Para trazer mais clareza ao assunto, eu notaria que minhas referências a socket e qualquer método de soquete se referem ao sistema operacional Linux.

    
por cg14 27.06.2018 / 01:04

2 respostas

1

Good find de Mike Penningtion (no comentários ) encontrando uma descrição técnica detalhada do caminho de uma solicitação pela Rede e backup (específico para o Linux OS 2005).

Uma visão mais detalhada, onde os seguintes passos foram extraídos de :

Observe que, embora as etapas listadas não sejam tão detalhadas quanto o documento mencionado acima, aproximadamente as etapas são:

O sistema operacional tem um descritor de arquivo dedicado para a porta ethernet rx,

The rx ring is a ring in the kernel memory where the network card transfers the incoming packet through DMA. The raw data which is stored in the rx ring structure is either copied into a sk buff structure.

Isso dispara um ISR para mover o pacote para a camada de rede. Note que isso escolhe se o pacote deve ser processado ou encaminhado (o que foi interessante, como imagino, talvez seja assim que o encaminhamento de ativação funciona, como para VPNs)

Se válido, passa para a camada IP. Ele verifica seu protocolo (do cabeçalho IP) e se o protocolo é TCP, chama a tcp v4 rcv fucntion, passando para a camada TCP.

E esta parte é crucial:

The next step for this function is to find an open socket for this incoming packet,

isso é feito chamando o tcp v4 lookup , no seguinte segmento de código:

sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source,
skb->nh.iph->daddr, ntohs(th->dest),
tcp_v4_iif(skb));

Essencialmente, eu entendo que há uma LUT mapeando o socket TCP para o endereço / portas de origem e destino da conexão do socket, como indicado por aquela chamada de função.

Se houver um soquete válido, os dados serão colocados em tcp_data_queue para continuar aumentando a pilha para o consumo de aplicativos.

    
por 27.06.2018 / 04:54
0

(do comentários )

I get encapsulation. So lets say the OS has a dedicated file descriptor that is open on the dedicated ethernet Rx port. It strips the ethernet header off a frame and passes it to some IP parse function, to strip the destination IP. It puts this in some struct, then sends it and the struct to the TCP layer. Here it strips it off the destination port and puts it in the same struct. Here, there has to be some mapping to the sockets file descriptor based on port and ip to put the data in a buffer assigned to the file descriptor. Thats my best go at it. But Id like to know what actually happens.

Uma versão bastante antiga do que você está procurando está aqui: Pilha de rede Linux . Eu estou tentando encontrar algo mais novo do que uma descrição de 2005 porque algumas das tripas do linux mudaram desde então. A maioria das informações do buffer de soquete é mantida em uma estrutura chamada sk_buff , que é uma estrutura linux que contém ponteiros para o identificador de soquete TCP, assim como todos os buffers de leitura / gravação de soquete.

Como o driver da NIC do Linux recebe informações da NIC em um determinado soquete, ele procura o espaço do buffer fora da instância de sk_buff (denominada skb ) e despeja os dados nos buffers apontados pelo skb .

    
por 27.06.2018 / 04:49