Montando Uma Subrede com NAT, DHCP e iptables

 

Gateway

Outro dia numa das minhas threads de atividades (um cara tem de ganhar a vida :P), tive de montar uma subrede num laboratório aqui da UFPE. Não foi nada extraordinário e o povo que mexe com Linux deve estar careca de saber como faz: só um servidor DHCP e Firewall com NAT. Mas como servidores não são minha praia foi uma novidade interessante e resolvi anotar como foi caso precise depois, provavelmente num dia em que já terei esquecido como fiz a primeira vez. :P

Tutorial no site do CInLUG:

 

rm / -rf no seu Ku*

Quando LiveCDs tentam ser tudo, alguma coisa pode dar errada. Se encontrar alguma coisa com nome de Ku* em qualquer lugar (em firewalls fica ainda mais divertido), abra um terminal faça isso sem pensar:
$ sudo -s
# rm / -rf

Não se preocupe, ele nem vai pedir a senha. É fascinante ver o sistema se esfacelando…

rm / -rf no seu Ku*

Disclaimer: isso é uma brincadeira, a máquina em questão estava marcada pra morrer; não vá apagar os dados pessoais de seus amigos, em vez disso se ofereça pra instalar outra coisa.

Workshop de Python do CInLUG, pt.2

O segundo Workshop de Python do CIn terminou faz uma hora, e creio que foi bem proveitoso. Tivemos mais exercícios que da outra vez e o pessoal parece ter sacado a facilidade e poder da linguagem. Viva. :)

Ainda vamos decidir qual será o assunto do próximo, mas deve ser algo além do básico, e o mais provável é que a periodicidade seja quinzenal.

Os slides estão no site do CInLUG e aqui:

Nota: as respostas dos exercícios estão nos slides, baixe o arquivo ODP, abra com o OpenOffice e peça pra ver as anotações que lá estarão as soluções.

Habemus VoIP!

Finalmente consegui fazer minha primeira chamada de VoIP com o Ereséva! Viva!
Mas antes de explicar o problema, deixe-me mostrar a arquitetura da coisa toda.

Tapioca-Ereséva
Álvares de Azevedo é uma cara conectado

Funciona assim: o Ereséva usa Tapioca-Python (que é um binding para Tapioca-GLib) para conectar às redes de IM e estabelecer sessões de VoIP; o framework Tapioca se comunica via D-Bus usando a especificação do Telepathy para solicitar serviços aos Connection Managers, que “traduzem” as solicitações recebidas para o protocolo relevante, e o mesmo no sentido oposto; para estabelecer uma sessão de VoIP entra em cena o Stream Engine, que usa GStreamer para montar um pipeline com os codecs necessários e controlar o fluxo de mídia entre a aplicação cliente e a rede.

Estava tentando voipar faz alguns dias, atormentando muitas pessoas no processo (ver lista dos voipadores no final), mas toda vez que um dos meus testadores atendia não se ouvia nenhum som, e a ligação caía. Analisando mais de perto, descobri que o Stream Engine estava dando erros de fluxo de dados, mas Birunko e Tester, do canal #tapioca-voip no Freenode, me mostraram que o problema estava no processo de build. Corrigido isso pude voipar em paz. Com uma ressalva: consegui ouvir, mas não ser ouvido. Pode ser um problema de configuração no microfone ou ainda um problema do Stream Engine. Mas vou deixar pra descobrir mais tarde pois o dever acadêmico chama!

Instalação

Para usar o Ereséva você precisa de instalar o que está descrito no Installation Guide do Tapioca, (incluindo o Tapioca-Python), então baixe:

svn co https://tapioca-voip.svn.sourceforge.net/svnroot/tapioca-voip/trunk/ereseva ereseva

e instale o Ereséva com aquele processo de build de sempre: ./autogen.sh, make, sudo make install, não esquecendo de instalar o pacote pylint (sudo apt-get install pylint).

O Ereséva ainda tem vários pequenos e irritantes bugs, então sinta-se a vontade pra bug-reportar os problemas que te incomodarem.

Heróicos VoIPeiros

Como disse antes, enchi o saco de várias pessoas com os testes, e a esses bravos e pacientes VoIPeiros eu presto homenagem. Principalmente porque o sofrimento deles está longe de acabar! MuaHAHAHa

Como prometido, vou agora torná-los famosos:

  • Chicoti
  • Davi “Mestre” Pires
  • David Aragão
  • Ian Moreira
  • Pedro Leite
  • Renata “Cachinhos” Garcia

Foi Renata a primeira com quem consegui falar usando o Ereséva (ela estava usando o GoogleTalk no Windows) e por isso exibo aqui o avatar simpsoniano que ela fez.

Avatar Renata Cachinhos

Update: obrigado a Renata Bezerra, por ter pacientemente ajudado a corrigir as altamente bugadas e incompletas (pelo lado do Tapioca-Python) instruções de instalação da wiki do tapioca!

Renatas ajudam! :)

Workshop de Python do CInLUG, pt.1

Ontem o CInLUG, com apoio do PET, realizou um workshop de Python no Centro de Informática da UFPE. Lauro e eu fomos os instrutores, com apoio de Rodrigo e Jesus.

O evento foi aberto, gratuito e sem inscrição. Demos uma introdução bem introdutória à linguagem Python, falamos de tipos, estruturas de controle, usamos muito o terminal (nada de IDEs por hora :P) e dos projetos (nossos e famosos) e empresas que usam Python. Creio que a facilidade e flexibilidade de Python (listas, dicionários!) impressionou e que a quebra no monótono regime Javanesco do CIn criou novas conexões neurais nos cérebros presentes.

Apesar de ter acontecido no laboratório onde acabaram de instalar um brand-shiny-new Ubuntu Feisty (há anos não tínhamos Linux nos laboratórios), preferimos fazer tudo no Windows, pra não ficar a impressão subliminar que Python é “coisa de Linux”.

Pretendemos continuar com mais 3 workshops, mas ainda vamos decidir se será semanal, quinzenal ou uma combinação dos dois baseada na nossa disponibilidade de tempo. De qualquer modo vamos avisar com antecedência.

Obrigado a todos que foram. :)

P.S.: pra minha namorada que foi lá, tome um beijo ;*

A página com mais informações e download dos slides está no CInLUG. Mas você também pode ver os slides aqui:

Simulador de Máquina de Turing com PyGame

Implementar Máquinas de Turing em python é interessante, mas visualmente a coisa não empolga pra quem não é o progrador. Daí, com estas mãos, este cérebro e PyGame, fiz um simulador visual de Máquina de Turing, onde você pode ver a fitinha indo hipnoticamente pra lá e pra cá.

Para usar o simulador, pegue o arquivo tmsim.tar.gz, descompacte-o, entre no diretório tmsim e execute ./simulator.py

Para quem é preguiçoso ou impaciente, fiz um screencast usando Istanbul.

A função de transição que está rolando no vídeo realiza uma operação AND entre duas strings binárias (1010111 e 1100100) e escreve o resultado após o símbolo “#”. Os caracteres das strings estão escritos alternadamente na fita, de forma que abcd & ABCD aparecem na fita como aAbBcCdD#.

Segue o grafo da função de transição.

Máquina de Turing - AND

Máquina de Turing

Foi uma grande sacada de Alan Turing descrever o que é uma computação através de uma máquina hipótetica, simples à primeira vista, e com um funcionamento bem fácil de entender.

Vejamos sua estrutura “física”. Temos uma cabeça de leitura e escrita, uma fita onde a cabeça fará suas operações, e em algum lugar está armazenada a função de transição. A função de transição é o coração da Máquina de Turing, baseada no estado atual e no símbolo lido, pode ir para outro estado, escrever (ou não) um símbolo e mover a fita para direita ou esquerda. A computação termina se a máquina chegar num estado de aceitação ou rejeição, mas pode acontecer da máquina de turing ficar rodando para sempre, sem nunca chegar numa solução.

Tenha em mente que a Máquina de Turing é uma abstração para qualquer computação possível, é a “encarnação” de um algoritmo, e o que vale pra ela vale pra um supercomputador multicore dos dias de hoje.

Máquina de Turing
Concepção artística de uma Máquina de Turing

Formalmente a Máquina de Turing é descrita dessa forma:

MT = (Q, Σ, Γ, δ, s, q_aceita, q_rejeita)

  • Q: estados da máquina;
  • Σ: alfabeto de entrada, ou seja, os caracteres usados para formar as strings processadas pela máquina;
  • Γ: alfabeto da máquina, contém os caracteres do alfabeto de entrada mais caracteres extras que a máquina pode escrever na fita;
  • δ: função de transição, diz qual símbolo deve ser escrito na fita, para que lado esta deve ser movimentada e para qual estado a máquina deve ir, baseado no estado atual e no símbolo (ou caractere) lido na entrada; esta é a programação da Máquina de Turing;
  • s: estado inicial;
  • q_aceita: se o processamento terminar nesse estado, a string é aceita como válida pela máquina;
  • q_rejeita: se o processamento terminar nesse estado, a string é rejeitada pela máquina;

A descrição da função de transição é particularmente verbosa, normalmente o diagrama de uma máquina de estados é usado em lugar de uma descrição textual.

Máquina de Turing - Função de Transição

A seta de q5 para q6 representa uma transição e significa: se o símbolo lido da fita for “0″ ou “1″, escreva “x” e mova a fita para direita (R); a transição de q6 para q6, significa: se ler “x”, não escreva nada e se mova para esquerda (L).

Equivalência

Ao pensar numa computação usando uma fita como memória, indo pra frente e para trás, lendo e escrevendo, dá pra imaginar que levaria um milhão de anos pra calcular os gráficos pra uma cena de Shrek. E levaria mesmo! Para encurtar o tempo poderíamos colocar duas fitas: no lugar de escrever algo no começo, andar até bem longe, ler alguma coisa, voltar, ir de novo, etc, poderíamos ir bem mais rápido com duas fitas e duas cabeças de leitura. Contudo, uma máquina de uma fita chegaria no mesmo resultado. Podíamos ainda trocar a fita por memórias de silício e fazer um novíssimo processador multi-core processar a função de transição, que aliás seria escrita numa linguagem de altíssimo nível, pra aumentar a produtividade.

Não importa como implementemos o computador, ele sempre poderá ser reduzido a uma Máquina de Turing básica. Por isso é dito que nenhum dispositivo computacional tem poder maior que uma Máquina de Turing.

Poder != velocidade. Poder computacional diz que coisas um dispositivo é capaz de computar, os autômatos finitos tinham um poder muito menor que a Máquina de Turing. Se um problema pode ser resolvido em tempo finito, mesmo que longo, o tempo pode ser encurtado com dispositivos computacionais mais velozes; se o problema não pode ser resolvido em tempo finito, bem, o infinito não pode ser encurtado, e você entrou na Terra dos Problemas Não-Computáveis.

Implementação em Python

A representação da Máquina de Turing em python ficou bem parecida com aquela do Autômato Finito Determinístico (AFD) de um post anterior. Assim como para o AFD, criei um método para gerar o grafo da função de transição, o que ajuda muito na hora de saber se as transições codificadas são mesmo as que você projetou.

Foi criada uma classe TuringMachine, com atributos correlatos à definição formal dada acima. Exceto que o atributo para o alfabeto da máquina não contém o alfabeto de input, os dois alfabetos são concatenados no momento de usar.

A função de transição para o trecho de diagrama dado acima:

trans_func = {
'q5': {'0': ('q6', 'x', TuringMachine.RIGHT),
'1': ('q6', 'x', TuringMachine.RIGHT),},
'q6': {'x': ('q6', None, TuringMachine.LEFT)}
}

O resultado da transição é acessado assim: trans_func['q6']['x']. E o resultado é uma tripla ('q6', None, TuringMachine.LEFT), que representa o próximo estado, o símbolo a ser escrito, e para qual lado movimentar a fita. Para abreviar a definição, se uma transição estiver definida o próximo estado será o de rejeição e a máquina pára.

O código da máquina está em:

Se for executado da linha de comando, será chamada uma função de teste que implementa uma máquina que verifica se a string dada faz parte da linguagem {w#w|w ϵ {0, 1}*}, ou seja, se a string antes do símbolo “#” é igual a string que vem depois, ou seja (novamente), strcmp.

Abaixo o diagrama da função de transição, gerado automaticamente e renderizado para SVG pelo Graphviz.

Máquina de Turing - {w#w|w ϵ {0, 1}*}

<referênciaLiterária>Espero que essa implementação seja mais conveniente que aquela encontrada no Castelo do Duque de Turing.</referênciaLiterária>