matheusd
Membros-
Total de ítens
8 -
Registro em
-
Última visita
Últimos Visitantes
O bloco dos últimos visitantes está desativado e não está sendo visualizado por outros usuários.
matheusd's Achievements
-
Tempo de Inicialização da unit ssl_openssl_lib.pas
matheusd replied to matheusd's tópico in Dúvidas Gerais sobre o ACBr
Pessoal, não sei se alguém pode achar relevante mas escrevi um pequeno artigo sobre o processo que usei pra descobrir onde estavam as demoras de inicialização do meu sistema (inclusive esse do openssl). Talvez seja útil pra mais alguém: http://matheusd.com/post/Profile_Delphi_Startup/ Código complementar: https://github.com/matheusd/DelphiProfileInit Até mais. -
Tempo de Inicialização da unit ssl_openssl_lib.pas
matheusd replied to matheusd's tópico in Dúvidas Gerais sobre o ACBr
@Waldir Paim Fiz o teste aqui do randPoll() e está ok! -
Tempo de Inicialização da unit ssl_openssl_lib.pas
matheusd replied to matheusd's tópico in Dúvidas Gerais sobre o ACBr
@Waldir Paim O header da synapse continua do mesmo jeito, com o RandScreen() (já conferi lá). Eu acho que o mais simples e que mantém retrocompatibilidade é a abaixo. Dessa forma, quem não definir a diretiva de compilação OPENSSL_NO_RAND_INIT, continua com o comportamento padrão (inicializar chamando o randPoll que é mais eficiente que o randScreen). Quem quiser definir e entender os riscos (na minha opinião, se estiver usando uma versão atualizada da openssl, nenhum) pode definir essa diretiva na compilação do programa para uma inicialização mais rápida. Fontes/Terceiros/synalist/ssl_openssl_lib.pas | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Fontes/Terceiros/synalist/ssl_openssl_lib.pas b/Fontes/Terceiros/synalist/ssl_openssl_lib.pas index 1f6647d..d8e58b6 100644 --- a/Fontes/Terceiros/synalist/ssl_openssl_lib.pas +++ b/Fontes/Terceiros/synalist/ssl_openssl_lib.pas @@ -1997,8 +1997,10 @@ begin _SslLoadErrorStrings; if assigned(_OPENSSLaddallalgorithms) then _OPENSSLaddallalgorithms; - if assigned(_RandScreen) then - _RandScreen; + {$IFNDEF OPENSSL_NO_RAND_INIT} + if assigned(_randPoll) then + _randPoll(); + {$ENDIF} if assigned(_CRYPTOnumlocks) and assigned(_CRYPTOsetlockingcallback) then InitLocks; {$ENDIF} -
Tempo de Inicialização da unit ssl_openssl_lib.pas
matheusd replied to matheusd's tópico in Dúvidas Gerais sobre o ACBr
Segundo [1], não é necessário fazer nenhuma inicialização mais. A própria biblioteca do openssl executa a inicialização no primeiro uso de alguma das funções RAND_XXXX. Ou seja, podemos remover essa inicialização do initOpenSSL porque na hora que qualquer função que precisar de números aleatórios for chamada, a openssl faz a inicialização automaticamente. E aí quem não usa em nenhum lugar, não precisa inicializar desnecessariamente. E já emendando, embora exista a rand_Screen, em nenhum lugar do código do acbr ou da Synapse é usado alguma outra função da família rand_XXXX. A não ser que esteja sendo chamada implicitamente em algum lugar de dentro da biblioteca do openssl (a função rand_bytes não foi nem importada na ssl_openssl_lib.pas. [1] https://wiki.openssl.org/index.php/Random_Numbers#Initialization -
Tempo de Inicialização da unit ssl_openssl_lib.pas
um tópico no fórum postou matheusd Dúvidas Gerais sobre o ACBr
Olá Pessoal, Estou rastreando os pontos mais críticos no tempo de inicialização do sistema da empresa onde trabalho. Um dos pontos que achei, foi na unit ssl_openssl_lib.pas, especificamente na inicialização da biblioteca (função initSSLInterface), mais especificamente na chamada da função randScreen(). Nos meus testes, a chamada pra essa única função atrasa a inicialização do sistema em 1 segundo. Segundo os links abaixo[1,2], essa chamada é legada e não é mais necessária. Proponho as seguintes alternativas: 1- Eliminar completamente essa chamada 2- Criar um define para selecionar se essa função deve ser executada assim que a biblioteca é inicializada ou não. Posso mandar um patch para essa alteração caso seja aceita. Alguém tem algum comentário? A favor? Contra? Referências: [1] http://security.stackexchange.com/questions/7718/openssl-rand-poll-good-enough [2] https://curl.haxx.se/mail/lib-2004-06/0133.html -
Segue o patch pra compatibilizar o Lazarus 64bits+Acbr+libxmlsec+linux 64bits Alterações: Criei o arquivo ACBrLibXML.pas que contém apenas as definições usadas pelo ACBR da libxml2, libxmlsec, libxmlsec-openssl e libxslt O carregamento das funções da dll é dinâmico ao invés de estático Em linux, tenta carregar a biblioteca com vários possíveis nomes (libxmlsec.so, libxmlsec1.so, libxmlsec1.so.1, etc) antes de emitir um erro Removi os arquivos antigos libxml2.pas (etc) e corrigi os uses relevantes Na unit ACBrDFeOpenSSL.pas removi o carregamento "mágico" da dll libxmlsec-openssl e deixei isso explícito na ACBrLibXML.pas Testei (instalei componentes, compilei um demo e executei o demo com sucesso): Importação de XML e impressão de DANFE (usando fortes-ce) Em Windows (compilação de 32 bits) Em Linux (lazarus de 64 bits, compilação de 64 bits) Eu não testei: Gerar XML com nova assinatura Validar assinatura de XML Se alguém fizer esse teste, por favor avise. Se o patch for aceitável para inclusão oficial no projeto ACBR, me dê um toque. 0001-Suporte-a-libxml2-em-Linux-de-64-bits.patch
-
@Ricardo David Consolo Eu consegui rodar um demo de impressão de DANFE com o Fortes em 64 bits sem problema (quero dizer, sem problema depois de corrigir os erros que eu postei) @gabriel.hilbig O problema **não** é o Ubuntu, eles não tem que dar solução pra nada (e eu nem esperaria uma solução deles mesmo se fosse problema deles). O problema é na importação do libxml feita pelo acbr. Pelo que eu verifiquei, o acbr usa muito poucas funções do libxml e libxmlsec. Vou tentar fazer uma unit de importação personalizada que só importa as definições utilizadas pelo acbr. Eu tentei gerar uma nova versão do libxml2.pas segundo as instruções do repo deles no github, mas dá muito problema.
-
@Ricardo David Consolo: Você conseguiu compilar em 32 ou 64 bits? Você compilou um demo completo de nfe usando o ACBR? @gabriel.hilbig: O travamento do Lazarus acontece porque ele só linka com pacotes de forma estática (sempre que você tenta instalar um pacote, o Lazarus dá um aviso e recompila/relinka ele). Quando há um erro de link em tempo de execução, ele trava e não dá pra recuperar (só recompilando o lazarus sem o pacote que provoca o travamento, mas não sei como fazer isso manualmente "de fora" do lazarus) então a solução mais simples é reinstalar. Eu consegui compilar e executar com sucesso um demo simples (uma aplicação em linha de comando) do acbr que faz o seguinte: carrega o xml de uma nfe e imprime o DANFE dessa nfe. Mas as alterações que eu precisei fazer pra isso são hacks, precisamos de uma solução mais consistente pra integração ao projeto (caso alguém tenha conseguido fazer um demo em 64 bits fazendo **menos** coisas que eu fiz, avise). Vou revisar abaixo tudo o que fiz até o momento (espero ainda validar e melhorar esse processo). Detalhe: **não** instalei os pacotes em design time, usei apenas para um demo em runtime). Meu ambiente: - VM Ubuntu **64 bits** (instalação em uma VM limpa, apenas com o SO básico versão desktop) - Instalação do lazarus 1.7 e FPC 3.0 (usado script disponível em www.getlazarus.org) - Nenhum pacote de biblioteca compilado via source (**tudo** via apt-get) - Instalado (via apt-get, pacote binário e -dev): libxml2, libxmlsec1, libxmlsec1-openssl, libxslt1 - Criado symlinks para as bibliotecas libxmlsec1 e libxmlsec1-openssl: - # ln -s /usr/lib/libxmlsec1.so /usr/lib/libxmlsec.so - # ln -s /usr/lib/libxmlsec1-openssl.so /usr/lib/libxmlsec-openssl.so Até aqui tudo é bem óbvio: no código da unit libxmlsec.pas a biblioteca dinâmica é referida como libxmlsec.so, mas o pacote do ubuntu não instala esse link, ele instala só com o sufixo da versão, então precisa criar o symlink pro lazarus achar. Nesse ponto, comecei a ter erros de compilação de que funções não estavam sendo encontradas (exemplo xmlSecCryptoAppInit). Verificando o libxmlsec.so com o utilitário nm do linux pra exportar os símbolos, verifiquei que essa biblioteca não tem essa função. Interpretando a documentação da libxmlsec, essa função é "mágica", dependendo do plugin específico que for usado (nss, openssl, etc) ela vai efetuar a chamada pra função desse plugin específico. Mas a versão compilada pro repositório do ubuntu (dedução minha, não cheguei a verificar) não implementa essa mágica, ele foi compilado pra usar uma seleção manual de provider de api crypto. Solução: Modifiquei o libxmlsec.pas pra pegar as funções a partir da biblioteca dinamica libxmlsec-openssl. Segue snippet de código: //arquivo libxmlsec.pas const {$IFDEF WIN32} LIBXMLSEC_SO = 'libxmlsec.dll'; {$ELSE} LIBXMLSEC_SO = 'libxmlsec.so'; LIBXMLSEC_OPENSSL_SO = 'libxmlsec-openssl.so'; {$DEFINE STATICLIBXMLSECOPENSSL} {$ENDIF} //... {$IFDEF STATICLIBXMLSECOPENSSL} function xmlSecCryptoAppInit (const config: PAnsiChar) : Longint; cdecl; external LIBXMLSEC_OPENSSL_SO name 'xmlSecOpenSSLAppInit'; //... correção de todas as outras funções xmlSecCrypto**** {$ELSE} function xmlSecCryptoAppInit (const config: PAnsiChar) : Longint; cdecl; external LIBXMLSEC_SO; //... funções tradicionais {$ENDIF} As partes relevantes da alteração são: trocar a biblioteca referenciada pelo external e usar um nome explícito de função pra mapear a função do provider (xmlSecOpenSSLAppInit) para a função "mágica" (xmlSecCryptoAppInit). Fazendo isso, consegui compilar todos os pacotes relevantes (**não instalei**, apenas compilei) e consegui buildar o meu demo. Porém comecei a ter erros durante a execução do programa, um segfault na função _dl_load_func_x("emptyExp") logo ao iniciar o programa (antes de executar qualquer instrução minha). Cavando mais um pouco, descobri que a exceção acontece na inicialização da unit libxml2.pas, quando (na inicialização) é tentado carregar o símbolo "emptyExp" de forma manual. Fiz vários experimentos, e parece que a origem do problema é quando (no Lazarus de 64 bits ou no executável de 64 bits, não consegui isolar em qual e também não verifiquei em uma versão de 32 bits) é misturado carregamento estático e dinâmico de biblioteca. Se eu carregar só estaticamente (declarando a função com external) funciona. Se eu usar apenas carregamento dinâmico (loadLibrary/getProcAddress) também funciona. O problema é misturar as duas técnicas, como nas bibliotecas do libxml. Eu fiz uma busca rápida e não achei nenhuma referência às variáveis carregadas dinamicamente (emptyExp, forbiddenExp, etc) das units do libxml2 (não só no libxml2.pas mas no libxmlsec.pas e libxslt.pas também usam o mesmo modelo de carregamento). Ou seja, elas estão nas units (porque o acbr importou essas units) mas não estão sendo efetivamente usadas (pelo menos as poucas que eu procurei). Então eu comentei o código de inicialização das units. Fazendo isso, eu consegui compilar e executar meu demo em linux 64 bits. A solução definitiva pra esse último problema (e a solução adequada pro problema do nome da dll do libxmlsec) é alterar as units de carregamento pra fazer **exclusivamente** carregamento dinâmico de dll. Eu **não** chequei todas as funcionalidades do acbr, apenas essa pequena funcionalidade do meu demo. Mas acho que é um ponto de partida pra quem por aí não está conseguindo progredir em usar o acbr no linux 64 bits. Se alguém conseguiu compilar e executar funcionalidades relativas a nfe em linux **64 bits** sem precisar fazer tudo isso que eu fiz (e preferencialmente sem precisar recompilar nenhuma biblioteca a partir dos fontes), dá um grito.