Pular para o conteúdo principal

Há cerca de 18 meses, escrevi um blog falando sobre mudanças na forma de aceitação do OpenVOS release 17.1. O que eu negligenciei em indicar foi que estas mudanças só têm efeito se o código da aplicação for baseado no POSIX. Recapitulando, antes da 17.1 STCP só responderia a um pedido de conexão de cliente se o código de aplicação do servidor tivesse chamado a rotina de aceitação. Se o código não tivesse chamado aceitar o pedido de conexão do cliente entraria em uma fila, mas não seria atendido. Uma vez que a aplicação chamada aceitasse, o STCP enviaria uma resposta de conexão. Se o cliente ainda estiver aguardando, a conexão será concluída naquele momento. Se o cliente já tivesse desistido, ele responderia à resposta da conexão com um reset, a STCP jogaria a conexão fora e a aceitação seria suspensa (assumindo o modo de bloqueio) e esperaria por outra conexão.

A Figura 1 mostra este cenário; as linhas de texto justificadas à esquerda são mensagens de status da aplicação do servidor, as linhas de pacote_monitor recuado (ligeiramente modificadas) são o resultado da atividade do cliente. A aplicação (acceptTestnoPosix) é iniciada e escuta na porta 12345, e uma vez ouvida, dorme por 300 segundos. O cliente então faz uma conexão à porta 12345 enviando um segmento TCP para a porta 12345 com a bandeira Syn (S) configurada. Ele tenta três vezes antes de desistir. Após 300 segundos, o aplicativo acorda e as chamadas são aceitas. O stack STCP responde ao cliente com um segmento TCP com as bandeiras Syn e Ack (SA) configuradas. Como o cliente não tem mais um registro da conexão se enviar um Reset (R), o STCP bloqueia neste ponto. Se o soquete estivesse em modo não-bloqueio, o aceite teria retornado com um erro EAGAIN.

acceptTestnoPosix 12345
Executando acceptTestnoPosix 12345
Dormir por 300 segundos

  11:04:45.923 R TCP 164.152.77.50 164.152.77.217 11071 12345 S
  11:04:48.925 R TCP 164.152.77.50 164.152.77.217 11071 12345 S
  11:04:54.937 R TCP 164.152.77.50 164.152.77.217 11071 12345 S

Pronto para aceitar uma conexão na porta número 12345
  11:09:41.852 TCP 164.152.77.217 164.152.77.77.50 12345 11071 SA 
  11:09:41.854 R TCP 164.152.77.50 164.152.77.217 11071 12345 R

Figura 1 - aceitar pré 17.1 ou pós 17.1 não-POSIX

 

Se a aplicação for baseada no POSIX, as coisas são diferentes (Figura 2). STCP responde ao pedido de conexão (S) imediatamente (SA). Depois de 300 segundos, a aplicação acorda, as chamadas são aceitas e a STCP retorna o soquete aceito.

acceptTestwithPosix 12345
Executando acceptTestnoPosix 12345
Dormir por 300 segundos

  10:58:43.962 R TCP 164.152.77.50 164.152.77.217 11024 12345 S
  10:58:43.964 TCP 164.152.77.217 164.152.77.77.50 12345 11024 SA 
  10:58:43.964 R TCP 164.152.77.50 164.152.77.217 11024 12345 A

Pronto para aceitar uma conexão na porta número 12345
Conexão aceita

Figura 2 - aceitar POSIX com base no poste 17.1

 

A diferença de comportamento pode ser crítica. Se o cliente estiver esperando uma resposta da aplicação do servidor após fazer uma conexão, ele pode demorar e fechar a conexão antes que a aplicação realmente aceite as chamadas.

Como você constrói uma aplicação com o POSIX? Primeiro a linha

#define _POSIX_C_SOURCE 200112L

deve ser a primeira linha da fonte de aplicação. Segundo o caminho da biblioteca

(disco_mestre)>sistema>biblioteca_de_objectos_de_posixos

precisa estar nos caminhos da biblioteca de objetos depois das bibliotecas STCP e antes da biblioteca C.

Como você pode saber se isso foi feito? Bem, você pode olhar para as bibliotecas de objetos com as quais a aplicação foi ligada usando o comando display_program_module -object_dirs

display_program_module acceptTestwithPosix -object_dirs      
     %azvos#m17_mas>SysAdmin>Noah_Davids>temp>acceptTestwithPosix.pm 

Mapa de Diretório de Objetos:

    11 diretórios de busca
     0 diretórios sem pesquisa
    11 diretórios no total

   DTC Directory Path

     1 %azvos#m17_mas>SysAdmin>Noah_Davids>temp
     2 %azvos#m17_mas>sistema>stcp>object_library
     3 %azvos#m17_mas>sistema>stcp>object_library>socket
     4 %azvos#m17_mas>sistema>stcp>object_library>net
     5 %azvos#m17_mas>sistema>stcp>object_library>common
     6 %azvos#m17_mas>sistema>biblioteca_de_objectosposix
     7 %azvos#m17_mas>sistema>c_objecto_biblioteca
     8 %azvos#m17_mas>sistema>objecto_biblioteca
     9 %azvos#m17_mas>opt>apache>lib
    10 %azvos#m17_mas>opt>openssl>lib
    11 %azvos#m17_mas>opt>mysql>lib>mysql

Mas isto não lhe diz se o #define faz parte do código fonte.

Se você puder executar o código, você pode olhar para as bandeiras do soquete, um programa baseado no POSIX terá o conjunto de bandeiras de soquete SF_POSIX. Por exemplo, tenho três programas aceitandoTestnoPosix, aceitandoTestwithPosix e aceitandoTestwithPosixPathOnly. Este último tinha o >system>posix_object_library directory nos caminhos da biblioteca mas não incluía o #define no código fonte. Note que esta é considerada uma combinação inválida. Somente a aplicação que estava ligada à biblioteca POSIX e tinha a declaração POSIX_SOURCE #define no código criou um socket com a bandeira SF_POSIX.

acceptTestnoPosix.pm 12345     
Executando acceptTestnoPosix 12345
Dormir por 300 segundos
               como: match posix; dump_stcbq -full -lport 12345     
               como:
acceptTestwithPosix.pm 12345
Executando acceptTestnoPosix 12345
Dormir por 300 segundos
               como: match posix; dump_stcbq -full -lport 12345
                                                   SF_POSIX
               como:  
acceptTestwithPosixPathOnly.pm 12345
Executando acceptTestnoPosix 12345
Dormir por 300 segundos
               como: match posix; dump_stcbq -full -lport 12345
               como:

Existe uma quarta possibilidade, o #define foi incluído na fonte mas a biblioteca posix_object_library não foi utilizada. Neste caso, a rotina do soquete retornará um erro.

acceptTestwithPosixDefineOnly 12345
Executando acceptTestnoPosix 12345
acceptTestnoPosix: não pode criar soquete de escuta: Aplicação construída  
+ incorretamente: O tempo de execução POSIX deve ser pesquisado antes do tempo de execução C.

Todos os comandos e utilitários STCP são construídos com o POSIX e eu recomendo fortemente que quaisquer aplicações que você construa também utilizem o POSIX.

© 2020 Stratus Technologies.