Gustavo | 17 Jan 03:08
Picon

[Lisp-br users] Espionando sockets

Olá, pessoal da lista,

Vou contar minha aventura com o sb-bsd-sockets.

Há um tempo atrás eu comecei a desenvolver uma interface para o
DBus<http://www.freedesktop.org/wiki/Software/dbus>usando o
libdbus <http://dbus.freedesktop.org/doc/dbus/api/html/index.html> + cffi,
mas parei (por falta de tempo). Depois visitei o cliki e vi que tinha um
projeto (cl-dbus <http://www.cliki.net/CL-DBUS>) começado, mas que usa
sockets diretamente, sem a necessidade de usar o libdbus. Usar sockets ao
invés da biblioteca é imensamente melhor, já que usar sockets:

- permite que você salve a imagem do lisp, pelo cffi você não pode fazer
isso pois tem que carregar de novo as bibliotecas dinâmicas
- é mais eficiente, não tem que ficar "traduzindo" os objetos Lisp e usar
aqueles "message-iterators"
- é mais simples, pois você não precisa criar uma abstração em cima de uma
biblioteca inflexível (libdbus é muito... C... fazer o quê?)
- ...

Mandei um e-mail para o desenvolvedor do projeto oferecendo ajuda. Ele me
respondeu dizendo que ele tinha desenvolvido uma função para enviar a
mensagem "Hello" (que é a primeira mensagem que o programa tem que enviar
para poder usar o protocolo). E disse que seria interessante se eu pudesse
capturar a mensagem "Hello" sendo enviada por outro aplicativo, para poder
comparar e ver o que há de errado.

Fiquei pensando: como eu vou fazer isso? Tive que pesquisar pela internet
como sockets funcionam (nunca havia usado sockets na vida), ver se dá para
espionar uma socket sendo usada por outro aplicativo... Não achei nada que
me ensinasse a fazer isso.

Então eu tive a idéia de usar cffi + libdbus (já sabia como libdbus
funciona, então...), criar um socket como servidor (usando o sbcl) e criar
outro socket conectado ao dbus-daemon (usando o dbus-launch para obter um
endereço de um socket) e fazer uma ponte entre os dois sockets. É claro que
tudo o que passasse por essa ponte eu gravaria em algum lugar para poder
examinar depois. Bom, essa idéia eu tive ontem à tarde, fiquei a tarde toda
e à noite para fazer isso, hoje de manhã, e senti que eu estava quase lá.
Comecei de novo algumas horas atrás e finalmente espionei uma conversa
através de um socket pela primeira vez na vida.

A minha maior dificuldade mesmo era que eu usava o socket-make-stream e
obtinha uma stream de entrada e saída, e usava essa stream pra tentar enviar
e receber os bytes, mas não chamava o force-output (achei que depois de um
tempo ele teria que escrever), entre outros detalhes (por exemplo, o
socket-accept retorna um socket, e esse socket é que deve ser usado para a
conversação).

Bom, alguém agora pode querer vir me falar que tem um jeito muito mais fácil
de fazer isso (e quebrar a minha cara por isso, falar que eu já devia saber
fazer isso...), mas o importante é que eu fiz, e sozinho, e funcionou. :)

Gustavo.

Gmane