Passa al contenuto principale

Circa 18 mesi fa ho scritto un blog parlando dei cambiamenti nel modo in cui l'accettazione funziona nella versione 17.1 di OpenVOS. Quello che ho trascurato di indicare è che questi cambiamenti hanno effetto solo se il codice dell'applicazione è basato su POSIX. Ricapitolando, prima della versione 17.1 STCP rispondeva a una richiesta di connessione del client solo se il codice applicativo del server aveva chiamato la routine di accettazione. Se il codice non avesse chiamato la richiesta di connessione del client, la richiesta di connessione del client sarebbe andata in coda ma non avrebbe ricevuto risposta. Una volta che l'applicazione chiamata accetta, STCP invierà una risposta di connessione. Se il client è ancora in attesa, la connessione si completa in quel momento. Se il client si fosse già arreso, risponderebbe alla risposta di connessione con un reset, STCP getterebbe via la connessione e l'accettazione si bloccherebbe (supponendo la modalità di blocco) e aspetterebbe un'altra connessione.

La figura 1 mostra questo scenario; le linee di testo giustificate a sinistra sono messaggi di stato dell'applicazione server, le linee frastagliate packet_monitor (leggermente modificate) sono il risultato dell'attività del client. L'applicazione (acceptTestnoPosix) viene avviata e ascolta sulla porta 12345, e una volta ascoltato va a dormire per 300 secondi. Il client effettua quindi una connessione alla porta 12345 inviando un segmento TCP alla porta 12345 con il flag Syn (S) impostato. Prova tre volte prima di rinunciare. Dopo 300 secondi l'applicazione si sveglia e le chiamate vengono accettate. Lo stack STCP risponde al client con un segmento TCP con i flag Syn e Ack (SA) impostati. Poiché il client non ha più un record della connessione se invia un Reset (R), STCP si blocca a questo punto. Se il socket fosse in modalità non-bloccante accept sarebbe tornato con un errore EAGAIN.

accettareTestnoPosix 12345
Esecuzione di acceptTestnoPosix 12345
Dormire per 300 secondi

  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 ad accettare un collegamento sulla porta numero 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 - accettare pre 17.1 o non-POSIX post 17.1

 

Se l'applicazione è basata su POSIX, le cose sono diverse (Figura 2). STCP risponde immediatamente alla richiesta di connessione (S) (SA). Poi dopo 300 secondi l'applicazione si sveglia, le chiamate accettano e STCP restituisce la presa accettata.

accettatoTestaconPosix 12345
Esecuzione di acceptTestnoPosix 12345
Dormire per 300 secondi

  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 ad accettare un collegamento sulla porta numero 12345
Connessione accettata

Figura 2 - accettare il post 17.1 basato su POSIX

 

La differenza di comportamento può essere critica. Se il client si aspetta una risposta dall'applicazione server dopo aver effettuato una connessione, può interrompere e chiudere la connessione prima che l'applicazione accetti effettivamente le chiamate.

Come si costruisce un'applicazione con POSIX? Prima la linea

#definire _POSIX_C_SOURCE 200112L

dovrebbe essere la prima riga della fonte dell'applicazione. In secondo luogo il percorso della libreria

(master_disk)>sistema>sistema>posix_object_library

deve essere nei percorsi della libreria degli oggetti dopo le librerie STCP e prima della libreria C.

Come si fa a capire se è stato fatto? Beh, si possono guardare le librerie di oggetti con cui l'applicazione è stata vincolata usando il comando display_program_module -object_dirs

display_programma_modulo_modulo_accettaTestwithPosix -oggetto_dirs      
     %azvos#m17_mas>SysAdmin>Noah_Davids>temp>temp>accettaTestività>conPosix.pm 

Mappa dell'elenco degli oggetti:

    11 directory di ricerca
     0 elenchi non di ricerca
    11 directory in tutto

   Percorso directory DTC

     1 %azvos#m17_mas>SysAdmin>Noah_Davids>temp
     2 %azvos#m17_mas>sistema>sistema>stcp>object_library
     3 %azvos#m17_mas>sistema>sistema>stcp>object_library>socket
     4 %azvos#m17_mas>sistema>sistema>stcp>object_library>net
     5 %azvos#m17_mas>sistema>sistema>stcp>oggetto>biblioteca>comune
     6 %azvos#m17_mas>sistema>sistema>posix_object_library
     7 %azvos#m17_mas>sistema>sistema>c_object_library
     8 %azvos#m17_mas>sistema>sistema>biblioteca_oggetto
     9 %azvos#m17_mas>opt>apache>lib
    10 %azvos#m17_mas>opt>openssl>lib
    11 %azvos#m17_mas>opt>mysql>lib>mysql

Ma questo non vi dice se il #define fa parte del codice sorgente.

Se è possibile eseguire il codice è possibile guardare i socket flag, un programma basato su POSIX avrà il socket flag SF_POSIX impostato. Per esempio, ho tre programmi acceptTestnoPosix, acceptTestwithPosix e acceptTestwithPosixPathOnly. Quest'ultimo aveva la directory >system>posix_object_library nei percorsi della libreria ma non includeva il #define nel codice sorgente. Si noti che questa è considerata una combinazione non valida. Solo l'applicazione che era legata alla libreria POSIX e che aveva l'istruzione POSIX_SOURCE #define nel codice ha creato un socket con il flag SF_POSIX.

accettareTestnoPosix.pm 12345     
Esecuzione di acceptTestnoPosix 12345
Dormire per 300 secondi
               come: match posix; dump_stcbq -full -lport 12345     
               come:
accettatoTestaconPosix.pm 12345
Esecuzione di acceptTestnoPosix 12345
Dormire per 300 secondi
               come: match posix; dump_stcbq -full -lport 12345
                                                   SF_POSIX
               come:  
Accettare le prove conPosixPathOnly.pm 12345
Esecuzione di acceptTestnoPosix 12345
Dormire per 300 secondi
               come: match posix; dump_stcbq -full -lport 12345
               come:

C'è una quarta possibilità, il #define è stato incluso nella fonte ma non è stato utilizzato il posix_object_library. In questo caso la routine del socket restituirà un errore.

Accettare le prove conPosixDefinireSolo 12345
Esecuzione di acceptTestnoPosix 12345
acceptTestnoPosix: non è possibile creare una presa di ascolto: Applicazione costruita  
+ erroneamente: Il tempo di esecuzione POSIX deve essere cercato prima del tempo di esecuzione C.

Tutti i comandi e le utilità STCP sono costruiti con POSIX e raccomando vivamente che tutte le applicazioni che si costruiscono utilizzino anche POSIX.

© 2020 Stratus Tecnologie.