segunda-feira, 19 de setembro de 2011

Arquitetura TCP/IP

A arquitetura internet foi criada pelo Departamento de Defesa dos Estados Unidos, com o objetivo de se ter uma rede interligando várias universidades e órgãos do governo de maneira descentralizada (ARPANET), para evitar a sua destruição no caso de ocorrência de uma guerra. Com o passar do tempo, esta idéia inicial perdeu o sentido e a infraestrutura foi aproveitada para se tornar o que hoje é a maior rede de computadores do mundo: a Internet.

Os padrões da internet não são criados por órgãos internacionais de padronização, como a ISO ou o IEEE, mas ela é uma arquitetura muito aceita, sendo chamada por isso como padrão "de facto", ao contrário do modelo OSI, considerado padrão "de jure". O corpo técnico que coordena a elaboração de protocolo e padrões da internet é o IAB (Internet Activity Board). Qualquer pessoa pode criar um protocolo para ser utilizado pela rede internet. Para isto, basta que ela documente este protocolo através de um RFC (Request for Comments), que pode ser acessado na Internet. Estes RFC's são analisados pelos membros da IAB que poderão sugerir mudanças e publicá-lo. Se após seis meses da publicação não houver nenhuma objeção, este protocolo se torna um Internet Standard.

A arquitetura internet se destaca pela simplicidade de seus protocolos e pela eficiência com que atinge o seu objetivo de interconectar sistemas heterogêneos.

Obs: cabe comentar aqui que por rede internet entende-se qualquer rede que utiliza os protocolos TCP/IP, enquanto que o termo Internet (com I maiúsculo) é utilizado para designar a Internet (conjunto de redes baseada na ARPANET, com milhões de usuários em todo o mundo).

Arquitetura internet

A arquitetura internet se baseia praticamente em um serviço de rede não orientado à conexão (datagrama não confiável), o Internet Protocol (IP) e em um serviço de transporte orientado à conexão, oferecido pelo Transmission Control Protocol (TCP). Juntos, estes protocolos se completam, oferecendo um serviço confiável de uma forma simples e eficiente.

A arquitetura internet se baseia em um modelo com quatro camadas (figura abaixo), onde cada uma executa um conjunto bem definido de funções de comunicação. No modelo em camadas da internet, não existe uma estruturação formal para cada camada, conforme ocorre no modelo OSI. Ela procura definir um protocolo próprio para cada camada, assim como a interface de comunicação entre duas camadas adjacentes.
Modelo em Camadas da Internet

Camada de rede de comunicação

Na camada de rede de comunicação da internet, não existe um padrão para a sub-rede de acesso, possibilitando a conexão de qualquer tipo de rede, desde que haja uma interface que compatibilize a tecnologia da rede com o protocolo IP. Desta forma, um número muito grande de tecnologias pode ser utilizado na sub-rede de acesso, como Ethernet, Token Ring, FDDI, X.25, Frame Relay, ATM, etc.

Para que todas estas tecnologias possam ser "vistas" pela rede internet, existe a necessidade de uma conversão de endereçamentos do formato utilizado pela sub-rede e o formato IP. Esta conversão é realizada pelos gateways, que tornam a interconexão das redes transparente para o usuário (figura abaixo).

Além das conversões de protocolos, os gateways são responsáveis pela função de roteamento das informações entre as sub-redes.
Interconexão de Sub-Redes à Rede Internet

Camada de interrede

A camada de interrede, também chamada de internet, é equivalente à camada de rede do modelo OSI. Nela são especificados vários protocolos, dentre os quais se destaca o IP (Internet Protocol).

O IP é um protocolo não orientado a conexão, cuja função é transferir blocos de dados denominados datagramas da origem até o destino, podendo passar inclusive por várias sub-redes (a origem e o destino são hosts identificados por endereços IP). A operação no modo datagrama é uma comunicação não confiável, não sendo usado nenhum reconhecimento fim-a-fim ou entre nós intermediários, nem qualquer tipo de controle de fluxo.

Nenhum mecanismo de controle de erro de dados é utilizado, apenas um controle de verificação do cabeçalho, para garantir que os gateways encaminhem as mensagens corretamente. Algumas das principais características do protocolo IP são as seguintes:

· Serviço de datagrama não confiável;

· Endereçamento hierárquico;

· Facilidade de fragmentação e remontagem de pacotes;

· Campo especial indicando qual o protocolo de transporte a ser utilizado no nível superior;

· Identificação da importância do datagrama e do nível de confiabilidade exigido;

· Descarte e controle de tempo de vida dos pacotes interredes no gateway. 

Endereçamento IP

O roteamento dos datagramas através das sub-redes são feitos baseados no seu endereço IP, números de 32 bits normalmente escritos como quatro octetos (em decimal), por exemplo 9.179.12.66. Devido ao fato de existirem redes dos mais variados tamanhos compondo a interrede, utiliza-se o conceito de classes de endereçamento:
Formato dos Endereços IP

Os endereços IP indicam o número da rede e o número do host, sendo que a classe A suporta até 128 redes com 16 milhões de hosts cada uma, a classe B 16384 redes com até 64 mil hosts cada uma, a classe C 2 milhões de redes com até 256 hosts cada uma e a classe D, onde um datagrama é dirigido a um grupo de hosts. Os endereços a partir de 1111 estão reservados para uso futuro.

A Internet utiliza a classe C para endereçamento de suas redes e máquinas. Quando um novo provedor de acesso se conecta à ela, ele recebe 256 endereços para serem utilizados pelos seus hosts (ou "usuários"). Como um provedor pode ter mais de 256 clientes, ele utiliza um esquema de alocação dinâmica de IP, ou seja, quando o usuário se conecta ao provedor de acesso, ele recebe um endereço IP, podendo desta forma haver até 256 usuários conectados simultaneamente a um provedor de acesso.

Formato do datagrama IP

O protocolo IP recebe da camada de transporte mensagens divididas em datagramas de 64 kbytes cada um, sendo que cada um destes é transmitido através da Internet, sendo ainda possivelmente fragmentados em unidades menores à medida em que passam por sub-redes. Ao chegarem ao seu destino, são remontados novamente pela camada de transporte, de forma a reconstituir a mensagem original.

O datagrama utilizado pelo protocolo IP consiste em um cabeçalho e um payload, sendo que o cabeçalho possui um comprimento fixo de 20 bytes mais um comprimento variável (figura abaixo).
Cabeçalho IP

O campo VERS identifica a versão do protocolo que montou o quadro. O campo HLEN informa o tamanho do quadro em palavras de 32 bits, pois este pode ser variável. O campo SERVICE TYPE indica às sub-redes o tipo de serviço que deve ser oferecido ao datagrama (por exemplo, para transmissão de voz digitalizada necessita-se mais de uma entrega rápida do que um controle rigoroso de erros, ao passo que para um serviço de transferência de arquivos, o tempo de entrega pode ser sacrificado para se obter um maior controle de erro).

O campo TOTAL LENGTH armazena o comprimento total do datagrama (dados e cabeçalho), com um valor máximo de 65.536 bytes. O campo IDENTIFICATION possibilita ao host determinar a que datagrama pertence um fragmento recém-chegado (todos os fragmentos de um datagrama possuem o mesmo valor). O campo FLAGS é composto de um bit não utilizado seguido por dois bits, DF e MF.

O DF significa Don't Fragment e indica que os gateways não devem fragmentar este datagrama (por incapacidade do destino juntar novamente os fragmentos). MF significa More Fragments, e é utilizado como dupla verificação do campo TOTAL LENGTH, sendo que todos os fragmentos, menos o último possuem este bit setado.

O FRAGMENT OFFSET informa a que posição no datagrama atual pertence o fragmento. O campo TIME TO LIVE é um contador utilizado para se limitar o tempo de vida de um pacote. Quando o datagrama é criado, este campo recebe um valor inicial, que é decrementado toda vez que passa por um gateway. Quando este contador atinge o valor zero, isto indica que a rede está em congestionamento ou que o datagrama está em loop, e o datagrama é descartado.

O campo PROTOCOL indica o protocolo que gerou o datagrama e que deve ser utilizado no destino. O campo HEADER CHECKSUM é utilizado pelos gateways para se fazer uma verificação do cabeçalho (apenas do cabeçalho, não dos dados), para que o gateway não roteie um datagrama que chegou com o endereço errado.

SOURCE IP ADRESS e DESTINATION IP ADRESS são, respectivamente, os endereços de host origem e destino. O campo IP OPTIONS é usado para o transporte de informações de segurança, roteamento na origem, relatório de erros, depuração, fixação da hora e outras. O campo PADDING possui tamanho variável e é utilizado para se garantir que o comprimento do cabeçalho do datagrama seja sempre um múltiplo inteiro de 32 bits. Finalmente, o campo DATA transporta os dados do datagrama.

Roteamento

O roteamento consiste no processo de escolha do caminho através do qual deve ser enviado o dado para o sistema destino. Caso o destino esteja localizado na mesma sub-rede, esta é uma tarefa fácil. Porém quando o destino se encontra em um sub-rede diferente, a transmissão dos dados é feita através de um gateway. O gateway faz o roteamento baseado no endereço IP de destino do datagrama. Se o gateway já estiver conectado à rede para onde o dado deve ser enviado, o problema acabou. Porém, o gateway pode não estar ligado diretamente à rede de destino. Neste caso, a partir da identificação da sub-rede, o endereço físico do próximo gateway na rota é obtido, através de processos de mapeamento. É importante observar que o gateway utilizado em uma rede internet possui funcionalidades distintas das normalmente aplicadas a ele nas redes OSI.

O roteamento pode, então, ser dividido em dois tipos:

· roteamento direto: quando o destino do datagrama se encontra na mesma sub-rede;

· roteamento indireto: quando o destino se encontra em outra sub-rede, necessitando de um gateway para o roteamento;

Para realizar o roteamento indireto, os gateways utilizam tabelas de roteamento, que armazenam informações sobre como atingir cada sub-rede da rede internet. Uma tabela de roteamento possui, tipicamente, entradas do tipo (N,G), onde N é um endereço IP (de destino) e G é o endereço IP do próximo gateway a ser utilizado para se atingir N (figura abaixo):
Tabela de Roteamento

Para diminuir o tamanho das tabelas de roteamento, existem algumas técnicas a serem utilizadas. Por exemplo, pode-se utilizar rotas default (pré-estabelecidas) para quando não se encontra referência na tabela sobre uma determinada rota. Este caso se aplica tipicamente para redes que possuem um único gateway, como por exemplo, departamentos de uma universidade ligados ao backbone por apenas um gateway. Ao invés de se ter uma rota para cada sub-rede, utiliza-se a rota default.

Algoritmos de Roteamento

Um algoritmo de roteamento é a parte do software da camada de rede que tem por objetivo decidir sobre qual linha de saída um pacote que chega deve ser transmitido. Para uma rede que trabalha com datagrama, a decisão deve ser tomada para cada pacote de dados que chega. Já para a rede que trabalha com circuitos virtuais, a decisão de roteamento deve ser tomada apenas quando se estabelece um circuito virtual.

Quando uma máquina M tem um datagrama a ser enviado, ela deve executar os seguintes passos:

· retirar do datagrama o endereço IP do destinatário (IPD);

· a partir do IPD obter o id.rede da sub-rede de destino (IRD);

· caso o IRD corresponda a uma rede na qual a máquina M está diretamente conectada, enviar o datagrama diretamente a IPD (roteamento direto);

· senão, se IRD aparece na tabela de roteamento, rotear o datagrama como especificado na tabela;

· senão, se foi especificado um gateway pré-definido na tabela de roteamento, rotear o datagrama conforme especificado na tabela;

· senão, indicar situação de erro utilizando, por exemplo, o protocolo ICMP.

Existem basicamente dois tipos de algoritmos utilizados em redes internet: Vetor-Distância e Estado-do-Enlace, porém não nos compete entrar em detalhes sobre eles neste momento.

Fragmentação e Remontagem de Datagramas

Como os datagramas IP atravessam redes das mais diversas tecnologias, os tamanhos dos quadros nem sempre devem ser os mesmos. Portanto deve haver uma certa flexibilidade em termos de tamanho de pacote a ser transmitido, de forma a este pacote se adaptar à sub-rede que vai atravessar.

Esta flexibilidade se dá através da facilidade de fragmentação e remontagem de datagramas.

Quando for necessário transmitir um datagrama maior do que o suportável pela rede, deve-se particionar o pacote em fragmentos. Estes fragmentos são transportados como se fossem datagramas independentes. Para poder recompor o datagrama original no destino, são utilizados alguns campos do cabeçalho do datagrama.

Quando o destino recebe o primeiro fragmento, inicia-se uma temporização para se aguardar o conjunto completo dos fragmentos que compõem o datagrama. Caso um dos fragmentos não chegue durante este intervalo, o datagrama é descartado, acarretando em uma perda de eficiência. 

Camada de Transporte

A camada de transporte tem o objetivo de prover uma comunicação confiável entre dois processos, estando eles ocorrendo dentro da mesma rede ou não. Ela deve garantir que os dados sejam entregues
livres de erros, em seqüência e sem perdas ou duplicação.

A Arquitetura Internet especifica dois tipos de protocolos na camada de transporte: o UDP (User Datagram Protocol) e o TCP (Transmission Control Protocol). O UDP é um protocolo não orientado à conexão que pode ser considerado como uma extensão do protocolo IP, e não oferece nenhuma garantia em relação à entrega dos dados ao destino.

Já o protocolo TCP oferece aos seus usuários um serviço de transferência confiável de dados, através da implementação de mecanismos de recuperação de dados perdidos, danificados ou recebidos fora de seqüência, minimizando o atraso na sua transmissão.

A cada fragmento transmitido é incorporado um número de seqüência, de forma a não se perder a ordem dos segmentos a serem juntados para formar o datagrama. Existe um mecanismo de reconhecimento para executar essa função que funciona da seguinte forma: o reconhecimento transmitido pelo receptor ao receber o segmento X é o número do próximo segmento que o receptor espera receber (X+1), indicando que já recebeu todos os segmentos anteriores a este. Através da análise dos números de segmento, o receptor pode ordenar os segmentos que chegaram fora de ordem e eliminar os segmentos duplicados.

Com base no checksum que é adicionado a cada segmento transmitido, os erros de transmissão são tratados e os segmentos danificados são descartados. Existe ainda um controle de fluxo baseado no envio da capacidade de recebimento do receptor, contado a partir do último byte recebido, ao transmissor. Desta forma o transmissor consegue controlar a quantidade de dados que são enviados ao receptor para não haver descarte de segmentos nem necessidade de retransmissão, que ocasionam a queda do desempenho da rede.

Para permitir que vários usuários (processos de aplicação) possam utilizar simultaneamente os serviços do protocolo TCP, foi criado o conceito de porta. Para não haver problemas de identificação de usuários, o identificador da porta é associado ao endereço IP onde a entidade TCP está sendo realizada, definindo assim um socket. A associação de portas a processos de aplicação (usuários) é tratada de forma independente por cada entidade TCP. No entanto, processos servidores que são muito utilizados, como FTP, Telnet, etc, são associados a portas fixas, divulgadas aos usuários. Uma conexão é identificada pelo par de sockets ligados em suas extremidades. Um socket local pode participar de várias conexões diferentes com sockets remotos.

Uma conexão pode ser utilizada para transportar dados em ambas as direções simultaneamente, ou seja, as conexões TCP são full-duplex.

É importante observar aqui que quando se fala que o TCP é orientado à conexão, não se fala em conexão a nível físico, mas sim a nível lógico. Este conceito pode ser compreendido através da figura
abaixo.
Serviços orientados e não orientados à conexão

No caso da figura acima, a máquina A quer se comunicar com a máquina B através de uma rede em anel utilizando TCP/IP. A única conexão física que existe entre A e B é através do anel, passando pelas máquinas C e D. A nível de IP, a comunicação não é orientada à conexão, portanto é muito simples enxergar que os dados possuem apenas dois caminhos para ir de A até B: através de C ou através de D.

A nível de TCP, porém, a comunicação entre os computadores A e B ocorre como se houvesse uma conexão direta entre eles. Isso implica que, se a nível de IP os dados podem chegar fora de ordem, o TCP tem que garantir a ordenação destes dados, de forma que eles sempre chegem na ordem correta, como aconteceria se houvesse uma conexão física direta entre A e B.

Camada de aplicação

As aplicações na arquitetura Internet, ao contrário do que ocorre com as OSI, são implementadas de uma maneira isolada, ou seja, não existe um padrão que defina como deve ser estruturada uma aplicação. Cada aplicação possui seu próprio padrão, correspondente a um RFC (Request for Comments).

RPC (Remote Procedure Call)

O RPC é um mecanismo criado para suportar aplicações distribuídas baseadas em um modelo cliente/servidor.

A aplicação cliente faz uma chamada de procedimento remoto onde o RPC, de forma automática, obtém os valores dos argumentos da chamada, monta a mensagem correspondente, a envia ao servidor e aguarda a resposta, armazenando os valores retornados nos argumentos definidos na chamada. Na realidade, o que ocorre é a mesma coisa que nas chamadas de funções locais comumente encontradas em aplicações, com a diferença que a execução real da função está ocorrendo em um local remoto.
Funcionamento de uma RPC

SMTP (Simple Mail Transfer Protocol)

O SMTP é o protocolo utilizado no correio eletrônico da arquitetura TCP/IP. Ela prevê uma interface com o usuário para enviar e receber mensagens que são armazenadas, inicialmente, em uma área de transferência de mensagens do sistema para serem, posteriormente, enviadas em background, conforme a figura abaixo.
Funcionamento do SMTP

O SMTP enxerga a mensagem como que dividida em duas partes: o corpo e o cabeçalho. O corpo da mensagem é onde são enviadas as mensagens propriamente ditas, sendo que o cabeçalho contém dados de endereçamento, assunto da mensagem etc. O protocolo SMTP não provê mecanismos sofisticados de controle de envio e recebimento de mensagens, tais como notificações, segurança de violação, criptografia dentre outros.

FTP (File Transfer Protocol)

O FTP provê serviços de transferência, renomeação e remoção de arquivos, bem como criação, remoção e modificação de diretórios, entre outros. Para que um serviço FTP seja prestado, são estabelecidas duas conexões TCP entre o cliente e o servidor: uma para a transferência dos dados e outra para controle. A confiabilidade das transferências de arquivos realizadas fica por conta do protocolo TCP, já que o FTP não possui nenhuma função de controle adicional sobre os arquivos, a não ser a exigência da senha do usuário para permitir a transferência. O FTP pode transmitir dois tipos de arquivos: arquivos texto (com dados no formato ASCII ou EBCDIC) ou arquivos binários (dados enviados como uma seqüência de bytes sem qualquer conversão).

TELNET (Terminal Virtual)

O TELNET é o protocolo utilizado para se permitir que o usuário de um sistema acesse um sistema remoto através de uma sessão de terminal, operando como se estivesse diretamente conectado neste sistema.

DNS (Domain Name System)

O DNS é o mecanismo utilizado pelo TCP/IP que define um sistema de nomes baseado em uma estrutura de árvore, que possibilita uma nomeação organizada de sistemas de domínio universal. O DNS estabelece a sintaxe de nomes e regras para delegação de autoridade sobre os nomes além de implementar um algoritmo computacional eficiente para mapear nomes em endereços.

Os nomes das máquinas são divididos em partes separadas por pontos correspondendo cada parte a um novo domínio de autoridade, em que o primeiro nome corresponde ao nível mais baixo e o último ao nível mais alto da hierarquia. No caso do nível mais alto, foram designados os seguintes nomes:

· ARPA - identificação do host da ARPA;

· COM - organizações comerciais;

· COUNTRY - qualquer país que utilize o padrão ISO3166 para nomes de país;

· EDU - instituições educacionais;

· GOV - instituições governamentais;

· INT - organizações internacionais;

· MIL - grupos militares;

· ORG - outras organizações.

A figura abaixo representa uma estrutura de nomes onde, por exemplo, o nome cctmn.inatel.br representa o domínio do CCTMN do INATEL.
Estrutura de nomes utilizada pelo DNS

Gerenciamento TCP/IP

O gerenciamento de uma rede TCP/IP se baseia no protocolo SNMP - Simple Network Management Protocol. O SNMP é um protocolo da camada de aplicação que atua sobre o UDP - User Datagram Protocol. A figura abaixo mostra a configuração típica da implementação do protocolo SNMP. O protocolo UDP é um protocolo não orientado à conexão, e a sua utilização (ao invés do TCP) se explica pelo fato de que não deve haver interrupções na comunicação de mensagens SNMP. No caso do TCP, uma interrupção em uma conexão, ou rota, influiria no desempenho do sistema de gerência. 

Ao se utilizar um serviço de datagrama, apesar de se obter um serviço de menor qualidade, esta limitação é contornada, pois em caso de impossibilidade de utilização de uma rota, outra rota é automaticamente escolhida.
SNMP

O gerenciamento de uma rede TCP/IP é baseado na estrutura agente-gerente, onde o gerente faz as requisições das operações a serem executadas sobre os recursos gerenciados. Estas requisições são enviadas ao agente, que executa as operações sobre os objetos gerenciados (abstrações dos recursos gerenciados para o agente). Através de uma interface, estas operações realizadas nos objetos gerenciados se refletem nos recursos gerenciados, e geralmente uma resposta é enviada de volta ao gerente, completando a operação de gerenciamento.

O protocolo SNMP é baseado no paradigma conhecido como fecth-store (busca-armazenamento), ou seja, todas as operações previstas para este protocolo são derivadas de operações básicas de busca e armazenamento. Estas operações básicas incluem:

· get-request: leitura do valor de uma variável;

· get-next-request: leitura do valor da próxima variável;

· get-response: resposta à operação de leitura;

· set-request: gravação do valor de uma variável;

· trap: notificação da ocorrência de um evento específico.

Segundo Marshall Rose, "o impacto do gerenciamento de rede adicionado para gerenciar os nós deve ser mínimo, refletindo o menor denominador comum. Cada nó é visto como tendo algumas variáveis. 

Pela leitura dos valores destas variáveis, o nó é monitorado. Alterando os valores destas variáveis, o nó é controlado".

Em decorrência disto, os agentes SNMP são simples e executam operações elementares, como estabelecer e obter valores das variáveis. O programa que analisa, manipula, combina ou aplica algum algoritmo sobre os dados deve residir no gerente. 

Comparação entre as arquiteturas TCP/IP e OSI

Atualmente, com a necessidade da utilização de modelos abertos em sistemas de comunicação, torna-se imprescindível conhecer os dois principais modelos que visam atender esta necessidade (o modelo OSI e o modelo TCP/IP) e suas diferenças.

A principal diferença entre os dois, é que o modelo OSI evoluiu de uma definição formal elaborada por comissões da ISO para o desenvolvimento de produtos, enquanto que o TCP/IP nasceu da necessidade do mercado e da demanda de produtos para resolver o problema de comunicação e a partir daí passou por uma série de implementações onde muitos produtos foram desenvolvidos fora da arquitetura internet, passando a ser incorporados a ela.

Vale então dizer que a arquitetura OSI é considerado um modelo de jure, enquanto que arquitetura internet é considerada um modelo de facto.

Analisando-se comparativamente a estrutura dos dois modelos (figura abaixo), pode-se observar que a parte referente às sub-redes de acesso da arquitetura internet corresponde à camada física, à de enlace e, parcialmente, à de rede do modelo OSI, sem que haja nenhuma padronização neste sentido.
O IP corresponde à camada de rede, enquanto o TCP e o UDP oferecem serviços semelhantes aos prestados, respectivamente, pelos protocolos de transporte orientados e não-orientados à conexão do modelo OSI. Nas camadas superiores, a arquitetura Internet coloca sob responsabilidade da aplicação os serviços fornecidos pelas camadas de sessão, apresentação e aplicação do modelo OSI.
Comparação entre as arquiteturas OSI e TCP/IP

O fato da arquitetura TCP/IP possuir menos camadas que o modelo OSI implica na sobrecarga de algumas camadas com funções que não lhe são específicas. Por exemplo, podemos citar a transferência de arquivos: no ambiente TCP/IP, as funções correspondentes à camada de apresentação OSI são desempenhadas pelo próprio protocolo de transferência de arquivos FTP. Por outro lado, o TCP/IP nos fornece aplicações simples, eficiente e de fácil implementação a nível de produtos. Uma das maiores limitações da arquitetura TCP/IP é quanto a sua capacidade de endereçamento, que já está se tornando limitada, devido ao crescimento da Internet.

Já a arquitetura OSI sofre críticas por apresentar "modelos e soluções acadêmicas" e objetivar atendimento a requisitos de propósito geral em detrimento de soluções imediatas, compatíveis com as exigências atuais dos usuários. É também criticada por não apresentar meios de migração entre as arquiteturas atualmente em funcionamento e suas soluções.

Diante desta situação, observa-se atualmente um emergente esforço de aproximação entre as duas arquiteturas, objetivando-se aproveitar o que cada uma tem de melhor a oferecer, de forma a se encontrar soluções mistas.

1 comentários:

C@chorro disse...

FAVORITEI TEU BLOG CARA.. muito bom esse documento

Postar um comentário