Pular para o conteúdo principal

Há cerca de 18 meses, escrevi um blog falando sobre as mudanças na forma como o accept funciona na versão 17.1 do OpenVOS. O que eu não mencionei foi que essas mudanças só entram em vigor se o código do aplicativo for baseado em POSIX. Para recapitular, antes da versão 17.1, o STCP só respondia a uma solicitação de conexão do cliente se o código do aplicativo do servidor tivesse chamado a rotina accept. Se o código não tivesse chamado o accept, a solicitação de conexão do cliente entraria em uma fila, mas não seria respondida. Assim que o aplicativo chamasse o accept, o STCP enviaria uma resposta de conexão. Se o cliente ainda estivesse aguardando, a conexão seria concluída naquele momento. Se o cliente já tivesse desistido, ele responderia à resposta de conexão com um reset, o STCP descartaria a conexão e o accept ficaria pendente (supondo o modo de bloqueio) e aguardaria outra conexão.

A Figura 1 mostra esse cenário; as linhas de texto alinhadas à esquerda são mensagens de status do aplicativo do servidor, as linhas recuadas packet_monitor (ligeiramente modificadas) são o resultado da atividade do cliente. O aplicativo (acceptTestnoPosix) é iniciado e fica à escuta na porta 12345 e, uma vez em escuta, entra em modo de espera por 300 segundos. O cliente então faz uma conexão com a porta 12345 enviando um segmento TCP para a porta 12345 com o sinalizador Syn (S) definido. Ele tenta três vezes antes de desistir. Após 300 segundos, o aplicativo acorda e chama accept. A pilha STCP responde ao cliente com um segmento TCP com os sinalizadores Syn e Ack (SA) definidos. 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 no modo não bloqueante, o accept teria retornado com um erro EAGAIN.

acceptTestnoPosix 12345
Executando acceptTestnoPosix 12345
Em espera 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 T TCP 164.152.77.217  164.152.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 o aplicativo for baseado em POSIX, as coisas são diferentes (Figura 2). O STCP responde à solicitação de conexão (S) imediatamente (SA). Então, após 300 segundos, o aplicativo é ativado, chama accept e o STCP retorna o soquete aceito.

acceptTestwithPosix 12345
Executando acceptTestnoPosix 12345
Em espera por 300 segundos

  10:58:43.962 R TCP 164.152.77.50   164.152.77.217  11024  12345 S
  10:58:43.964 T TCP 164.152.77.217  164.152.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 postagem baseada em POSIX 17.1

 

A diferença de comportamento pode ser crítica. Se o cliente estiver esperando uma resposta do aplicativo servidor após estabelecer uma conexão, ele pode expirar e fechar a conexão antes que o aplicativo realmente chame accept.

Como você cria um aplicativo com POSIX? Primeiro, a linha

#define _POSIX_C_SOURCE 200112L

deve ser a primeira linha do código-fonte do aplicativo. Em segundo lugar, o caminho da biblioteca

(disco_mestre)>sistema>biblioteca_de_objetos_posix

precisa estar nos caminhos da biblioteca de objetos após as bibliotecas STCP e antes da biblioteca C.

Como você pode saber se isso foi feito? Bem, você pode verificar as bibliotecas de objetos às quais o aplicativo foi vinculado usando o comando display_program_module -object_dirs.

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

Mapa do diretório de objetos:

    11  diretórios de pesquisa  
     0  diretórios sem pesquisa  
    11  diretórios no total  
  
   DTC  Caminho do diretório  
  
     1  %azvos#m17_mas>SysAdmin>Noah_Davids>temp
     2  %azvos#m17_mas>system>stcp>object_library 
     3  %azvos#m17_mas>system>stcp>object_library>socket 
     4  %azvos#m17_mas>system>stcp>object_library>net
     5  %azvos#m17_mas>system>stcp>object_library>common
6  %azvos#m17_mas>system>posix_object_library
7  %azvos#m17_mas>system>c_object_library
     8  %azvos#m17_mas>system>object_library
     9  %azvos#m17_mas>opt>apache>lib
    10  %azvos#m17_mas>opt>openssl>lib
    11  %azvos#m17_mas>opt>mysql>lib>mysql

Mas isso não indica se o #define faz parte do código-fonte.

Se você puder executar o código, poderá verificar os sinalizadores do soquete. Um programa baseado em POSIX terá o sinalizador de soquete SF_POSIX definido. Por exemplo, tenho três programas: acceptTestnoPosix, acceptTestwithPosix e acceptTestwithPosixPathOnly. O último tinha o diretório >system>posix_object_library nos caminhos da biblioteca, mas não incluía o #define no código-fonte. Observe que essa combinação é considerada inválida. Somente o aplicativo que estava vinculado à biblioteca POSIX e tinha a instrução #define POSIX_SOURCE no código criou um soquete com o sinalizador SF_POSIX.

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

Há uma quarta possibilidade: o #define foi incluído na fonte, mas a posix_object_library não foi usada. Nesse caso, a rotina do soquete retornará um erro.

acceptTestwithPosixDefineOnly 12345
Executando acceptTestnoPosix 12345
acceptTestnoPosix: não é possível criar soquete de escuta: Aplicativo compilado incorretamente: o tempo de execução POSIX deve ser pesquisado antes do tempo de execução C.

Todos os comandos e utilitários do STCP são criados com POSIX e recomendo fortemente que todos os aplicativos que você criar também utilizem POSIX.

© 2024 Stratus Technologies.