Universidade de Aveiro
|
|
|
- João Pedro Candal Mota
- 10 Há anos
- Visualizações:
Transcrição
1 Universidade de Aveiro Departamento de Electrónica e Telecomunicações Arquitectura de Qualidade de Serviço para Suporte de Serviços e Aplicações Multimédia Projecto Realizado por: Nuno Rafael Gomes da Silva, aluno nº e, Paulo Renato Tavares da Silva, aluno nº Orientadores: Professora Susana Sargento, Departamento de Electrónica e de Telecomunicações da Universidade de Aveiro; Professor Rui Pedro de Magalhães Claro Prior, Faculdade de Engenharia da Universidade do Porto.
2 Índice 1 - Introdução Objectivos do projecto Alguns conceitos O que é a Qualidade de Serviço QoS? O que é o DiffServ? O que é o IntServ? O Protocolo RSVP Mensagens RSVP Estilos de reserva Modelo de reserva Controlo de tráfego Escalonamento dos pacotes Controlo de admissão Classificador de pacotes A Arquitectura Scalable Reservation-Based QoS - SRBQ Classes de Serviço Reserva de recursos Label switching Expiração de reservas (Soft-states) O protocolo de sinalização Mensagens de sinalização Funcionamento do protocolo de sinalização Funcionamento do Deamon Funcionamento inicial e processador de pacotes Funcionamento do módulo de comunicação com a API Funcionamento da função manipuladora do SIGALRM Funcionamento dos blocos principais Instalação do signal de controlo do SIGALRM Receber pacote Criar reserva Criar reserva temporal Confirmar reserva Programar próxima reserva Label válido? IP destino pertence a esta máquina? Os Problemas Encontrados e as Soluções Propostas Acesso a zonas de memória não alocadas Método de expiração de reservas (implementação dos soft-states ) Envio de pacotes SResvRefresh Endereço de origem e identificação da reserva no router seguinte e anterior Comportamento hop by hop Sincronização dos relógios dos computadores Modificações feitas no pc para agir como um router Erros possíveis de acontecer na rede e a sua solução Recursos insuficientes no interface de rede...55 Página 2/113
3 Recursos insuficientes na alocação de memória Recursos insuficientes de processamento Mudanças de rota na rede Biblioteca de comunicação com o deamon (API) Modo de utilização da API Testes realizados Teste ao funcionamento do protocolo de sinalização Resultados obtidos Modelo de controlo de tráfego Protocolo de sinalização Soluções inacabadas Conclusões Modelo de controlo de tráfego Protocolo de sinalização Bibliografia Agradecimentos Anexos...77 Página 3/113
4 Índice de figuras Figura 1: Funcionamento do protocolo RSVP...10 Figura 2: Troca de mensagens RSVP...14 Figura 3: Exemplo de utilização da arquitectura RSVP...19 Figura 4: Modelo de controlo de tráfego...21 Figura 5: Modelo de controlo de tráfego com múltiplas classes AF...22 Figura 6: Formato do pacote SResvInit para um fluxo GS...29 Figura 7: Formato do pacote SResvInit para um fluxo AF...30 Figura 8: Formato do pacote SResvRefresh...31 Figura 9: Formato do pacote SResvStat...32 Figura 10: Formato do pacote SResvTear...33 Figura 11: Funcionamento normal do protocolo de sinalização SRBQ...35 Figura 12: Funcionamento do protocolo de sinalização SRBQ num caso de existência de erro...37 Figura 13: Fluxograma do funcionamento do Deamon...42 Figura 14: Fluxograma do funcionamento do módulo de comunicação com a API...44 Figura 15: Fluxograma do funcionamento da função manipuladora do SIGALRM...46 Figura 16: Configuração para modelo de teste do controlo de tráfego...61 Figura 17: Configuração do modelo de teste do protocolo...62 Índice de tabelas Tabela 1: Valores para os tipos de mensagens usados...34 Tabela 2: Valores para a classe e tipo dos objectos usados...34 Tabela 3: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 1º teste...64 Tabela 4: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 2º teste...66 Tabela 5: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 3º teste...67 Tabela 6: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 4º teste...69 Tabela 7: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 5º teste...70 Tabela 8: Resultados obtidos para o desempenho do protocolo de sinalização em função do processamento...71 Página 4/113
5 1 - Introdução Na Internet actual, os recursos disponíveis são distribuídos por todos os utilizadores dum modo igual, segundo um modelo de melhor esforço (Best-effort). No entanto, face ao aparecimento de novos serviços e aplicações, os requisitos da Internet actual estão a mudar. Com efeito, as exigências das aplicações, dependendo de muitos factores, implicam que, cada fluxo de informação deva ser tratado com relação ao fim a qual se destina. Para tentar resolver este problema, o IETF (The Internet Engeneering Task Force) propôs duas arquitecturas: os servidos integrados (IntServ) e os serviços diferenciados (DiffServ). No modelo IntServ as reservas são criadas individualmente para cada fluxo através do protocolo Resource Reservation Protocol (RSVP) e propondo, para além do serviço de melhor esforço, duas classes de serviços: o Serviço Garantido, para fluxos que necessitam de limites fixos de atraso e, o Serviço de Carga Controlada, para fluxos que necessitam de um limite probabilístico de atraso. Por sua vez, no modelo DiffServ não existe qualquer reserva de recursos, uma vez que neste modelo os fluxos são agregados de acordo com as suas características. Para distinguir os diferentes tipos de fluxos é usado o campo DiffServ Code Point (DSCP) do cabeçalho Internet Protocol (IP) e a cada campo corresponde um tratamento diferente de encaminhamento, o qual se chama Per Hop Behaviour (PHB). Como é evidente, cada um destes modelos apresenta vantagens e inconvenientes, quer a nível de escalabilidade quer a nível da eficiência, pelo que foram propostos vários modelos, não garantindo, porém, nenhum a simultaneidade entre um QoS estrito e diferenciado e a maximização do uso dos recurso da rede sem problemas de escalabilidade. A arquitectura que propomos permite um QoS ponto a ponto, com base na reserva de recursos para fluxos agregados, quer em redes de trânsito (core), quer em redes de acesso. Este modelo é essencialmente baseado na arquitectura DiffServ, em que os fluxos Página 5/113
6 são agregados por classe de serviço, com base no campo DSCP do cabeçalho IP. O policiamento é feito nos routers de acesso (edge), conseguindo-se, assim, obter conformidade com os recursos agregados. Neste modelo a sinalização é efectuada previamente antes de se iniciar o fluxo de dados, de modo a melhorar a utilização dos recursos disponíveis. As reservas são unidireccionais, iniciadas pelo emissor e utiliza o conceito de soft-states, que permite uma eficiente gestão e controlo das expirações das reservas. O protocolo de sinalização é baseado em RSVP, pois assim podemos obter uma maior funcionalidade para o modelo. Com vista à diminuição do esforço computacional dos routers e aumento da própria escalabilidade do protocolo de sinalização, implementou-se um sistema de identificação de reservas por etiqueta (label). Nestas, cada label representa a posição de memória em que os dados relativos à própria reserva estão guardados em cada router ao longo do caminho, o que torna forçoso implementar um mecanismo de troca de labels. Todavia, através da oportunidade oferecida por este mecanismo (aceder ao dados da reserva directamente), é possível obter um aumento da escalabilidade do protocolo e, concomitantemente, uma diminuição do peso computacional no processamento de mensagens. Do mesmo modo, e com idêntico objectivo, foram usadas reservas soft. Neste caso cada reserva detém um tempo associado, através do qual ela será terminada, caso não seja refrescada. Este método, além de ser independente do número de reservas existentes em cada router, pode ser implementados com baixa complexidade computacional. Em suma, o modelo implementado garante QoS ponto a ponto com escalabilidade. Página 6/113
7 2 - Objectivos do projecto O presente projecto pretende desenvolver um protótipo laboratorial de uma arquitectura de QoS no sistema operativo Linux. Os blocos constituintes dos elementos de rede são compostos pelos seguintes módulos: Um módulo responsável pela implementação do escalonamento dos pacotes; Vários módulos de policiamento; Vários módulos de formatação do tráfego; Um módulo responsável pela implementação do protocolo de sinalização entre os elementos da rede. A implementação da arquitectura ora proposta permitirá a configuração de uma plataforma laboratorial de teste a ser usada para a validação e a avaliação do desempenho da arquitectura. As actividades a realizar no âmbito do projecto situam-se maioritariamente nas áreas da programação em C e das redes de telecomunicações. Página 7/113
8 3 - Alguns conceitos No âmbito deste projecto existe a necessidade da compreensão de alguns conceitos, por isso, temos de compreender o que pretendemos com o conceito de QoS e compreender a diferença entre o modelo de serviços diferenciados e o modelo de serviços integrados já que esta arquitectura aproveita as vantagens de cada uma delas O que é a Qualidade de Serviço QoS? A Qualidade de Serviço (QoS) consiste na capacidade de uma rede de telecomunicações controlar a sua largura de banda, controlar o jitter e tempos de latência (para o caso de tráfego em tempo real e interactivo) e melhorar as capacidades de perdas de pacotes, ou reduzir ao máximo este problema. Deve, ainda, ser capaz de priorizar certos fluxos evitando ao máximo a perda de informação noutros fluxos com menos prioridade. Duma maneira geral, a QoS permite melhorar o serviço para certos fluxos de informação, através do aumento da prioridade de fluxos mais importantes e limitando outros com menos prioridade. Em caso de congestionamento é possível aumentar a prioridade dos fluxos mais importantes (caso dos fluxos tempo-real e interactivos), pelo que se perdem pacotes de fluxos com menos prioridade, evitando-se, deste modo, a perda de pacotes nos fluxos importantes O que é o DiffServ? Os Serviços diferenciados (DiffServ) traduz uma arquitectura que permite trabalhar com diferentes tipos ou níveis de serviço para o tráfego da rede, tendo surgido a fim de possibilitar um melhor e máximo aproveitamento da largura de banda disponível numa rede IP. Página 8/113
9 Esta arquitectura consiste no uso do byte ToS (Type of Service) de cada pacote IP para marcar a prioridade ou nível de serviço que cada pacote necessita, com a vantagem de não afectar fluxos encriptados, já que o byte ToS de cada pacote não é encriptado O que é o IntServ? O IntServ (Serviços integrados) é um modelo que permite o tráfego de fluxos numa rede através de níveis de serviço. Permite que sejam criadas reservas para cada fluxo, reservas estas que podem ser quer a nível de largura de banda como outras características (tamanho dos pacotes máximo, taxas máximas, etc.). A desvantagem do IntServ é que os fluxos necessitam de ser reservados explicitamente e refrescadas posteriormente. Este processo adciona tráfego à rede o que pode causar problemas de escalabilidade. Página 9/113
10 4 - O Protocolo RSVP O protocolo Reservation Protocol (RSVP) foi desenvolvido para permitir que as aplicações possam requisitar diferentes QoS para os seus fluxos de dados. Esta potencialidade exige que estejam presentes dois requisitos: os elementos de rede (tais como routers, que devem adequar-se aos mecanismos de controlo da qualidade de serviço para garantir a entrega dos pacotes de dados) e a aplicação, que deve ser capaz de fornecer os parâmetro ideais de QoS. O protocolo RSVP é usado a partir duma aplicação, permitindo que esta possa requisitar qualidade de serviço específica da rede. Além disso, possibilita que a qualidade de serviço actue tanto em computadores de trabalho como em routers, cabendo ao protocolo estabelecer e manter as condições para o serviço requisitado. Figura 1: Funcionamento do protocolo RSVP Como podemos ver através da figura 1, o protocolo RSVP negoceia a reserva de recursos num único sentido de cada vez, ou seja, de forma simplex. Este protocolo não realiza o transporte de dados. Ele consiste simplesmente num protocolo de controlo, estando ao mesmo nível de outros protocolos, tais como o ICMP (Internet Control Página 10/113
11 Message Protocol), o IGMP (Internet Group Menagement Protocol) ou protocolos de roteamento. Ao receptor cabe a responsabilidade de requisitar uma qualidade de serviço específica, seguidamente reiniciada em intervalos de tempos específicos. Existem vários conceitos associados a este protocolo: Sessão O protocolo RSVP define como sessão todo o processo de troca de mensagens de sinalização e de dados, através do qual se relacionam as camadas de transporte de todos os participantes da comunicação, podendo esta ser unicast ou multicast. Cada sessão é tratada independentemente e pode ser considerada como um conceito genérico, dado que uma sessão pode ser estabelecida baseando-se em valores de QoS diferentes dos requisitados pelo receptor inicialmente. Tal facto deve-se à liberdade que o gestor possui em unir recursos ao longo do caminho de dados da aplicação, sendo que objectivo principal traduz-se no aproveitamento máximo dos recursos disponíveis. Ao efectuar esta política, os valores dos parâmetros de QoS requisitados poderão sofrer alterações, desde que estas não impliquem a perda de qualidade para uma comunicação já estabelecida. Soft-state O protocolo RSVP é baseado na noção de soft-state, como sendo o estado que um determinado elemento, pertencente ao percurso de dados de um determinado par fontedestino, se encontra quando uma reserva está estabelecida. O soft-state dá-se quando uma mensagem de reserva é recebida e realizada no elemento; este estado é periodicamente realimentado pelos receptores. Ao invés de entregar à rede a responsabilidade em detectar e responder a falhas, o RSVP delega aos receptores o trabalho de reenviar periodicamente as requisições do Página 11/113
12 serviço que esta a usar. Caso ocorra alguma falha, somente uma nova requisição do serviço irá restabelecer o soft-state nos routers Mensagens RSVP Uma série de mensagens devem ser trocadas entre as aplicações e os elementos da rede para requisitar correctamente a qualidade de serviço para uma determinada sessão. Após a definição da sessão, serão trocadas mensagens de controlo RSVP. As mensagens RSVP fundamentais são RESV e PATH. Cada uma deverá explicitamente requisitar o QoS através de objectos descritores do tráfego e filtros. Dependendo do serviço de QoS, esses objectos possuirão alterações a fim de comportar os diversos parâmetros de interesse. A mensagem PATH, enviada pelo transmissor, é propagada pelo caminho unicast ou multicast, seguindo a rota informada pelos mecanismos de encaminhamento até aos receptores. Um elemento no caminho de dados, ao receber uma mensagem PATH, criará um estado designado por PATH State. As mensagens deste tipo armazenam o estado de cada nó por onde ela transitou. A mensagem RESV, enviada pelo receptor, contém um descritor de fluxo, definindo o QoS aceite pelo receptor em função da pedida pela mensagem PATH. Mediante a troca destas mensagens, o protocolo toma uma série de decisões, como por exemplo, aceitar ou não o novo fluxo de dados, criando um ambiente para que os recursos sejam reservados. Cada parâmetro utilizado para requisitar o QoS está representado nas mensagens do RSVP. Através da análise dos parâmetros contidos nos objectos RSVP, algumas simplificações podem ser feitas, de forma a agrupar fluxos distintos de uma mesma Página 12/113
13 sessão que possuam características comuns. Tal tarefa, apesar da complexidade, proporciona, quando possível, uma economia de recursos utilizados, principalmente em termos de largura de banda. Para que isto possa ocorrer, é essencial a utilização dos estilos de reserva Estilos de reserva Uma série de mensagens devem ser trocadas entre as aplicações e os elementos da rede para requisitar correctamente a qualidade de serviço para uma determinada sessão. Após a definição da sessão, serão trocadas mensagens de controlo RSVP. As mensagens RSVP fundamentais são RESV e PATH. Cada uma deverá explicitamente requisitar o QoS através de objectos descritores do tráfego e filtros. Dependendo do serviço de QoS, esses objectos possuirão alterações a fim de comportar os diversos parâmetros de interesse. A mensagem PATH, enviada pelo transmissor, é propagada pelo caminho unicast ou multicast, seguindo a rota informada pelos mecanismos de encaminhamento até aos receptores. Um elemento no caminho de dados, ao receber uma mensagem PATH, criará um estado designado por PATH State. As mensagens deste tipo armazenam o estado de cada nó por onde ela transitou. A mensagem RESV, enviada pelo receptor, contém um descritor de fluxo, definindo o QoS aceite pelo receptor em função da pedida pela mensagem PATH. Mediante a troca destas mensagens, o protocolo toma uma série de decisões, como por exemplo, aceitar ou não o novo fluxo de dados, criando um ambiente para que os recursos sejam reservados. Cada parâmetro utilizado para requisitar o QoS está representado nas mensagens do RSVP. Página 13/113
14 Através da análise dos parâmetros contidos nos objectos RSVP, algumas simplificações podem ser feitas, de forma a agrupar fluxos distintos de uma mesma sessão que possuam características comuns. Tal tarefa, apesar da complexidade, proporciona, quando possível, uma economia de recursos utilizados, principalmente em termos de largura de banda. Para que isto possa ocorrer, é essencial a utilização dos estilos de reserva Modelo de reserva Considerando um cenário simples, ponto-a-ponto, em que todos os elementos compreendem o protocolo RSVP. Em cada nó, além do gerenciador de recursos, responsável pela reserva, existem módulos de controlo de tráfego e policiamento que auxiliam o RSVP na tarefa de reservar os recursos pretendidos. Consierando a figura 2 como o modelo de exemplo, T1 é uma máquina que contém uma aplicação com necessidades de QoS; R1, uma outra máquina, irá receber os dados dessa aplicação e G nós intermédios. A aplicação em T1, para iniciar a sua transmissão, envia uma mensagem de controlo, cujo nome é PATH. Esta seguirá o seu caminho, pelos diversos nós até chegar a R1. A mensagem PATH contém um cabeçalho RSVP e todas as informações sobre o tráfego que a aplicação em T1 espera gerar. Em cada nó G existente entre T1 e R1 e que pertença ao caminho da reserva, será criado um estado chamado de PATH State. Figura 2: Troca de mensagens RSVP Página 14/113
15 Ao chegar a R1, este analisa as informações contidas na mensagem PATH e selecciona os parâmetros de reserva desejados, criando desta forma uma outra mensagem de reserva, RESV. Esta será enviada no sentido contrário ao da mensagem PATH, e provocará a transição do estado dos nós intermédios G de PATH State para o estado SOFT State, e informa ao mesmo tempo todos os nós das condições dos parâmetros de QoS da reserva realizada por R1 e propriedades do caminho entre ambos Controlo de tráfego Além das propriedades específicas que os protocolos de encaminhamento devem fornecer para a realização da reserva na rede, outras funções devem ser utilizadas para que exista o QoS que as aplicações pretendem. O RSVP actua em conjunto com outros módulos, ditos de controlo de tráfego: escalonador de pacotes, classificador de pacotes e controlo de admissão. Estes actuam não só nos elementos finais (emissores e receptores) como também em todos os nós ao longo da Path Escalonamento dos pacotes A função básica do escalonamento traduz-se em implementar uma política para servir os pacotes na fila de saída. O esquema mais utilizado é o FIFO ( First-In First-Out). Nele, os pacotes são servidos estritamente na ordem de chegada. Entre os muitos esquemas propostos, talvez o mais simples seja um esquema de prioridades, onde o pacote que tenha maior prioridade seja servido em primeiro lugar. Um problema inerente a esta solução consiste em que na presença de pacotes de alta prioridade, aqueles que não possuem nenhum tipo de privilégio, pelo que podem ser bastante atrasados, ou até mesmo, provocar atraso indefinido. Página 15/113
16 É possível criar o esquema de Weigth Fair Queueing (WFQ) que tenta obter uma maior justiça no escalonamento através da atribuição de pesos aos diversos fluxos de saída. Outro mecanismo de escalonamento que se poderá criar é o Class Based Queue ( CBQ). Neste caso, os pacotes dos diversos fluxos são enquadrados em diversas classes, organizadas de forma a criar um esquema de prioridades entre os fluxos de dados da saída Controlo de admissão O controlo de admissão implementa um algoritmo de decisão que um router ou uma máquina utiliza com o fim de determinar se um novo fluxo de dados poderá ser ou não aceite. A decisão deverá ser tomada de forma a não comprometer os fluxos previamente aceites pela máquina ou nó. O controlo de admissão é evocado em cada ponto para fazer uma decisão simples: aceitar ou rejeitar, no momento que a requisição do fluxo chega a esse ponto Classificador de pacotes Em qualquer rede de dados, que se baseia em circuitos virtuais, o QoS do fluxo é conhecida no momento do estabelecimento da sessão. Todos os pacotes subsequentes deste fluxo serão identificados pelo número do circuito virtual, o que torna mais fácil a classificação dos pacotes. Outro método consiste em permitir ao módulo classificador identificar mais campos da área do cabeçalho dos pacotes, tais como o endereço da fonte, porta e número do protocolo. Uma determinada sequência de vídeo, por exemplo, poderia ser reconhecida por uma porta particular. Aprofundando tal busca, poderíamos obter um método onde Página 16/113
17 seria possível permitir a investigação mais rigorosa dos pacotes, talvez até à área de dados, a fim de identificar alguma característica da aplicação. Página 17/113
18 5 - A Arquitectura Scalable Reservation-Based QoS - SRBQ A arquitectura Scalable Reservation-Based QoS (S.R.B.Q.), assegura a qualidade de serviço (QoS) numa rede IPv4, através da pré-reserva de fluxos, com a finalidade de garantir atraso controlado, perdas mínimas e ao mesmo tempo máxima eficiência e escalabilidade. Neste modelo, baseado no modelo DiffServ (DS), é usado, de igual modo, o campo DiffServ code point (DSCP) para efectuar a classificação dos fluxos, os quais serão agregados e policiados se necessário, ou seja, de acordo com a classe de serviço. Esta agregação de fluxos permite criar os seguintes tipos de fluxos principais: Serviço Garantido (GS), que é uma classe que se baseia num forte QoS para que exista sempre garantia de entrega do pacote no destino e um atraso mínimo; Envio Assegurado (AF), ou Assured Forwarding que simula o comportamento de redes best-effort não muito saturadas; Sinalização (SIG), para que os pacotes de sinalização tenham garantia de entrega, para o correcto funcionamento do modelo; Melhor Esforço (BE), ou Best-effort, para o qual todos os outros pacotes são encaminhados. As reservas são unidireccionais, iniciadas pelo emissor e incluem o conceito de softstate. Esta aproximação permite uma maior simplicidade do protocolo de sinalização, e uma maior facilidade de implementação. Existem quatro tipos de pacotes no protocolo de sinalização: SResvInit, para criar uma reserva; SResvRefresh, para renovar a reserva; SResvStat para transmitir mensagens de erro ou de sucesso; SResvTear, para terminar uma reserva. Concomitantemente, a troca de mensagens de sinalização é hop-by-hop, ou seja, os pacotes de sinalização são sempre enviados para o router seguinte, criando um caminho Página 18/113
19 virtual por onde os pacotes pertencentes ao fluxo têm de passar, mesmo em routers core. Rede de transito C E C E Receptor Rede de acesso Emissor Rede de acesso E A A E C C C C Figura 3: Exemplo de utilização da arquitectura RSVP Ao longo deste caminho é efectuado controlo de admissão para cada fluxo individual. No entanto, através dum mecanismo de troca de labels, que representam cada reserva, em cada router, directamente no endereço físico de memória, possibilita-se existir escalabilidade, para além de se simplificar ao máximo o protocolo de sinalização e diminuir-se ao máximo o esforço computacional dos routers. Ou seja, cada router necessita de saber o seu endereço físico, onde tem a informação relativa à reserva, e o endereço físico onde o router anterior e o router seguinte têm as reservas correspondentes. Nestas posições de memória é guardada toda a informação relativa à própria reserva, onde se inclui também os endereços IP do router anterior e do router seguinte. Isto permite uma maior rapidez no acesso à informação relativa à reserva, pois o acesso é directo, ao inverso de ser necessário efectuar uma procura para descobrir onde se Página 19/113
20 encontra a reserva. Para além deste processo de troca de labels, o esforço computacional é diminuindo através do conceito de soft-timer, o qual é de baixa complexidade, mas com funcionalidade suficiente para um bom funcionamento da arquitectura. Podemos considerar vários tipos de redes importantes para esta arquitectura: redes de acesso (edge) e redes de trânsito (core). Um exemplo bastante simples pode ser encontrado na figura Classes de Serviço Além do serviço de melhor esforço (Best effort), este modelo está dotado de outras duas classes de serviço: - Serviço garantido (Guarenteed Service - GS), que permite a obtenção de QoS estrito em termos de garantia de entrega e atraso mínimo; - Envio garantido (Assured forwarding - AF), que simula o comportamento de redes com o serviço de melhor esforço, ligeiramente saturadas. As reservas para a classe GS são caracterizadas por um token bucket, no qual se define um tamanho e uma taxa de envio dos pacotes. As reservas para a classe AF são caracterizadas por três marcas: os pacotes que excedam as duas primeiras marcas recebem um aumento da probabilidade de perdas. Caso ultrapassem a terceira marca, é, então, perdido. Este modelo assenta na arquitectura de serviços diferenciados (DiffServ) para definir a classe de serviço no DSCP (DiffServ Code Point). A arquitectura em estudo baseia-se igualmente nesta estratégia, tendo um comportamento para os fluxos GS com os mesmos princípios que os fluxos EF (Expedicted Forwarding) no DiffServ: baixo atraso e uma garantia de entrega máxima. A classe AF tem como objectivo garantir um serviço melhor do que o serviço de melhor esforço (Best Effort) através do uso de marcas (cuja função é definir a probabilidade de perdas num fluxo AF através da sua largura de banda de ocupação). Todas estas marcas são definidas previamente através do protocolo de sinalização. Página 20/113
21 Neste caso, o modelo de filas (queuing model), figura 4, baseia-se em prioridades. Através deste conceito é possível atribuir máxima prioridade a fluxos de serviço garantido, logrando, desse modo, melhorar o comportamento de fluxos altamente sensíveis ao atraso, fluxo de serviço garantido. A disciplina de serviço desta classe é assenta num token bucket, que não é mais do que um FIFO (First-In First-Out), de tamanho e taxa de envio de pacotes definidos pelo protocolo de sinalização. O segundo nível de prioridade é associado à fila de pacotes de sinalização, para se garanta o correcto funcionamento da arquitectura. Por sua vez, a disciplina de serviço baseia-se igualmente num token bucket. Os fluxos de AF têm a prioridade seguinte: baseia-se num modelo mais complexo, pois possui 3 filas virtuais, uma para cada parâmetro do fluxo. A disciplina de serviço interna baseia-se num GRED (Generalized Random Early Detection). Finalmente, no que concerne à disciplina de melhor esforço (Best Effort), esta que simula o comportamento normal das redes actuais. O modelo agora em análise é caracterizado por deter a prioridade mais baixa de todo o modelo de filas e pela disciplina conseguida através dum simples FIFO. Note-se que tanto esta fila, como a fila de sinalização não estão de todo sujeitas a controlo de admissão. O escalonador principal alicerça-se num PRIO (Priority Qdisc) onde, a cada pacote recebido, é atribuída uma classe de serviço através do DSCP. Para obter o DSCP e se proceder à sua classificação é usado a disciplina de serviço DSMARK. Figura 4: Modelo de controlo de tráfego Página 21/113
22 No entanto, pode-se considerar um modelo um pouco mais completo, em que a classe AF é decomposta em várias classes AF, como representado na figura 5, através da disiplina DWRR (Deficit Weighted Round Robin). Figura 5: Modelo de controlo de tráfego com múltiplas classes AF Reserva de recursos O controlo de admissão é feito em todos os nós ao longo do caminho definido para o fluxo, dependendo o algoritmo do tipo de fluxo em questão. Para um fluxo GS temos de efectuar controlo de admissão, pois é imperativo garantir que existe largura de banda suficiente e espaço no buffer de cada router. Por outro lado, num fluxo AF, é premente efectuar controlo de admissão, mas dum modo mais leve, pois a admissão é feita através de policiamento que define quando um determinado fluxo deve sofrer um aumento da sua probabilidade de perdas e qual a taxa de perdas. Os fluxos GS baseiam-se num token bucket cujos parâmetros dependem dos fluxos existentes. Cada router faz a soma de todos os fluxos GS existentes, criando assim a partilha da mesma classe de serviço para todos os fluxos GS. Podemos dizer que r sum = ri e b sum = bi, em que r i e b i são respectivamente, a taxa do token bucket e i i o tamanho do mesmo para cada fluxo. Neste momento, é necessário verificar se o valor de rsum é compatível com a largura de banda disponível no interface em questão, pois se este valor não satisfizer a condição rsum Bmin bsum + MTU, onde R 0 é a largura de R 0 Página 22/113
23 banda do interface, a reserva não pode ser efectuada. Este método, devido à sua simplicidade, torna-se computacionalmente pouco exigente e garante escalabilidade ao sistema. Os fluxos AF são caracterizados por três marcas: duas que vão ser usadas para a degradação do serviço e uma outra para definir taxa de perdas. As três marcas representam igualmente a soma das marcas de todos os fluxos AF em cada router. Neste caso, algumas perdas de pacotes são toleráveis e o controlo da admissão não é tão crítico como no caso dos fluxos GS. Contudo, atente-se que é necessário disponibilizar sempre alguma largura de banda para os fluxos de melhor esforço Disciplina de serviço - Traffic Shaping Como supra mencionado, o modelo de classe de serviço implementado, tem a sua maior prioridade para o serviço GS. Neste caso, é usado um token bucket com os parâmetros sendo a soma dos valores individuais de cada fluxo GS ( r sum e b sum ). Este facto revela-se de extrema importância, pois neste caso a perdas de pacotes, no policiamento feito no interface de entrada do nó seguinte, não é tolerável. No entanto, devido ao uso de um token bucket partilhado para todos os fluxos, alguns problemas podem surgir. Esses problemas podem ocorrer quando todos os fluxos GS param de transmitir por algum tempo. Isto provoca o enchimento do bucket de tokens. No entanto, se estiver a ser enviado algum pacote numa outra classe de serviço, tal facto vai fazer com que a classe GS não possa transmitir, apesar da prioridade que possui. Como o bucket já se encontra cheio de tokens, não vai acumular mais. Isto pode-se traduzir numa redução da taxa de serviço para a classe GS, e eventualmente, conduzir à perda de pacotes. A classe reservada aos pacotes de sinalização, apesar de não necessitar de controlo de admissão, necessita de shaping para resguardar alguma largura de banda para os fluxos do serviço AF. Como esta classe não necessita de policiamento à entrada do router seguinte, a disciplina de serviço pode ser simplificada a uma disciplina cuja taxa seja conservativa, pois, de facto a disciplina usada foi um token bucket. De salientar que Página 23/113
24 nesta classe a existência de perdas, desde que poucas, não é grave. A disciplina de serviço usada para a classe AF exige que seja empregue uma taxa conservativa para que os fluxos best-effort não sejam muito prejudicados com falta de largura de banda Policiamento Podemos considerar quatro diferentes tipos de nós nesta arquitectura: os nós finais, os nós de acesso, os nós edge e nós core. Todos tem de compreender a sinalização e respeitar o modelo de disciplina dos serviços. Os nós de acesso garantem um policiamento por fluxo, garantindo assim que cada fluxo ao longo do caminho não exceda os seus limites. Os nós edge apenas suportam policiamento dos fluxos agregados por interface, pois, nesta situação, não é necessário que operem o policiamento por fluxo individual, já que os nós de acesso já o fizeram. Além disso, podem, no caso de fluxos AF, remarcar para uma probabilidade de perdas maior. Todavia, é necessário garantir que este processo seja color-aware. Ou seja, temos de garantir que por causa dum fluxo mal comportado não se prejudiquem outros. Por outro lado, os nós core, não necessitam de qualquer tipo de policiamento, pois pressupõe-se que os nós anteriores o fizeram, tornando-se desnecessário. Ao contrário do shaping que é feito nos interfaces de saída para os fluxos agregados, o policiamento é efectuado no interface de entrada individualmente, fluxo a fluxo. Esta é uma operação forçosa dada a necessidade de garantir que todos os fluxos respeitam os seus parâmetros. Para evitar que ocorram perdas de pacotes nos fluxos GS, temos de garantir que o bucket do policiamento sofra aumentos equivalentes aos do shaper do interface de saída do router anterior, ou seja, r GS max MTU, ou duma maneira simplificada MTU. R 0 Página 24/113
25 6 - Label switching Com o intuito de diminuir o esforço computacional e aumentar a escalabilidade do protocolo de sinalização, principalmente nos routers core, este modelo está dotado dum mecanismo de identificação de reservas por labels. Cada label representa, em cada router, a posição de memória alocada que contem a estrutura de dados com a informação relativa à reserva. Existem 3 campos relativos a este processo em cada estrutura de dados: O campo label, que representa a reserva localmente; O campo b_label que representa a reserva no router anterior (usado em mensagens enviadas para trás) O campo f_label que representa a reserva no router seguinte. Este processo cria uma ligação da reserva ao longo do caminho, em que o label num nó será o b_label no seguinte, e o f_label será o label no anterior. Deste modo, podemos, em qualquer altura, obter a identificação da reserva para o nó onde necessitamos de enviar a mensagem. Este mecanismo pode igualmente servir para detectar alterações da rota da reserva, a diferença entre o campo RSVP_Hop e o valor guardado na estrutura de dados relativa à reserva em questão indica que o caminho foi alterado, podendo assim proceder à respectiva alteração da rota. Página 25/113
26 7 - Expiração de reservas (Soft-states) O método usado para controlar os tempos de expiração tem com base os Soft reservations, visto que permite a possibilidade de adaptação da rede às constantes mudanças de condições. Para tal torna-se necessário o uso de tempos de expiração, tempo a partir do qual a reserva é eliminada. Nesta situação usamos um conjunto de 8 filas do tipo First-In First-Out (FIFO), em que cada fila corresponde ao valor de REX, para guardar o tempo em que a reserva irá expirar. Uma vez criada a reserva, é colocada no final da fila correspondente, para garantir que no topo de cada fila temos a próxima reserva a expirar. O processo de programação do alarme para a expiração fica assim simplificado pois apenas tem de verificar o tempo no topo de cada fila. Este processo implica o periódico envio de mensagens de refrescamento entre os nós pertencentes ao caminho da reserva. Este período de tempo corresponde a ¼ do tempo de expiração. Deste modo, garante-se a não expiração da reserva, designadamente no caso de não recebimento da mensagem de refrescamento ou de perda de pacotes ao longo do percurso. Esta garantia só é viável pois no final de outro ¼ de tempo é enviada uma nova mensagem de refrescamento. Como quanto menor for o tempo de expiração duma reserva, maior irá ser o número de mensagens de refrescamento necessárias para manter a reserva activa ao longo dos vários nós, torna-se importante o uso dum valor de REX adequado. Salientamos que o uso de valores de tempos de expiração baixos deve ser evitado, pois aumenta a carga de processamento do router e o número de mensagens de sinalização na rede, podendo mesmo chegar ao ponto de provocar perdas de pacotes de sinalização devido a congestionamentos nos nós. Assinala-se vivamente que é de evitar o uso de tempos de expiração inferiores a 4 segundos, pois tal facto torna impossível o cumprimento do tempo de ¼ para os refrescamentos. Por outro lado, o uso de valores de tempos de expiração altos implica, em caso de erros, recursos alocados desnecessariamente, o que, em redes congestionadas, pode ser muito relevante. Página 26/113
27 8 - O protocolo de sinalização O protocolo de sinalização implementado baseia-se num modo hop-by-hop, ou seja, os pacotes são enviados router a router, para que em todos os routers pelos quais uma reserva necessite de cruzar até ao destino final possam processar e modificar os controlos de tráfego respectivo. Ao mesmo tempo cada reserva é unidireccional, e iniciadas pelo emissor. Tal facto serve para simplificar todo o processo de reserva e para ser mais eficiente. Este protocolo baseia-se no protocolo RSVP, dado tratar-se de um protocolo muito conhecido e usado, bem como por disponibilizar algumas funcionalidades ao nosso protocolo. Pretende-se, porém, que este protocolo seja mais escalável do que o próprio RSVP, através da simplicidade do processo de efectuar uma reserva, ao uso de reservas temporárias (soft-state) e ao uso dum processo de identificação da reserva simples e computacionalmente eficaz Mensagens de sinalização Ao protocolo RSVP criou-se uma extensão através da criação de 4 novos tipos de mensagens: SResvInit (utilizada para iniciar uma reserva. É sempre iniciada pelo emissor e tem como destino o receptor do fluxo. Em mais nenhum momento da reserva é usada a não ser para alteração da rota (path); SResvRefresh (refresca o processamento de reservas. São enviadas igualmente pelo emissor e têm como destino o receptor do fluxo. São enviadas regularmente durante toda a reserva); SResvStat (envia mensagens de sucesso ou de erro); SResvTear (usa-se para terminar uma reserva, é enviada pelo emissor quando Página 27/113
28 este pretender o fim da respectiva reserva). Existem várias classes de objectos para cada tipo de pacote: Session, Filter_spec, Label_setup, Label, RSVP_hop, SResv_parms, GSFlowspec, AFflowspec e Error_spec. Os objectos usados neste protocolo estão segundo a RFC Houve, todavia, a necessidade de criar 4 novos objectos: GSFlowspec (define o tamanho e a taxa do tocken bucket); AFFlowspec (define as taxas de degradação e a taxa de perdas); Label/Label_setup (define o endereço de memória para a reserva, quer na própria máquina, quer na máquina seguinte, para uso no processo de confirmação de reserva), SResv_parms (especifica, através do campo PHB, a classe de serviço, para além de ser usado para definir o msgid. Este último serve para associar mensagens a SResvStat e o valor do tempo de expiração da reserva, rex. Este valor tem 3 bits e está numa escala logarítmica de base 2, por isso tem de ser convertido através duma potencia: REX tempo = 2. Tal operação permite tempos entre 1 segundo e 128 segundos, o que é ideal para uma implementação dos tempos de expiração com base num algoritmo soft-state). Página 28/113
29 Figura 6: Formato do pacote SResvInit para um fluxo GS A mensagem SResvInit, representada na figura 6, tem no seu cabeçalho IP a opção Router_alert, de acordo com o RFC Com este pacote é possível dar toda a informação aos routers sobre os IP s de origem e destino, bem como as portas (através dos objectos Filter_spec e Session ), obter o label (identificação da reserva) no router anterior ( Label_setup ), o IP do router anterior pelo caminho usado ( RSVP Hop ), o intervalo de tempo usado para o refrescamento da reserva ( Sresv_parms ) e as especificações do fluxo. Página 29/113
30 Figura 7: Formato do pacote SResvInit para um fluxo AF A mensagem representada pela figura 7, pode igualmente ser usada para iniciar uma reserva do tipo AF, através da alteração do objecto Flow_spec, que, neste caso, inclui informação relativa às taxas de degradação e de perdas. Todos os outros valores supra descritos são os mesmos usados para o caso duma reserva Garanted Service (GS). Página 30/113
31 Figura 8: Formato do pacote SResvRefresh As mensagens de refrescamento, figura 8, contêm informações relativas à reserva em questão. Aquilata-se o uso do objecto Setup que torna possível o envio de mensagens de erro ao router anterior, quer em caso de mudanças de rota, quer em casos de reservas inexistentes. As mudanças de rotas são viáveis de detectar através do objecto RSVP_Hop, pois se este for diferente ao guardado em memória na máquina significa que houve uma alteração no caminho do fluxo e os procedimentos relativos à mudança de toda a informação guardada nos routers têm de ser invocados. Todos os outros campos acima apresentados são os mesmos que para uma mensagem SResvInit. Página 31/113
32 Figura 9: Formato do pacote SResvStat No tipo de mensagem representado na igura 9, SResvStat, é de salientar que a opção Router_Alert não existe, pois este tipo de mensagem necessita de ser enviado dum modo hop-by-hop. Ou seja, a mensagem é enviada dum router para o seguinte, segundo o caminho guardado em memória da reserva. Este sistema é necessário uma vez que se pretende assegurar a recepção da informação pretendida por todos os routers que estão a fazer o caminho da reserva, quer em caso de sucesso, quer em caso de erro. Neste caso é de relevar o objecto Error_spec, usado para informar os outros routers no caminho da reserva do sucesso da reserva ou do erro. Tal operação pode ser feita através do campo error code. Os valores usados nesta implementação foram do valor zero (0) para o caso de sucesso, um (1) no caso de mudança de rota e dois (2) no caso de reserva inexistente, não foram implementados mais tipos de erros. Neste objecto encontra-se também incluído o endereço IP do router em que ocorreu o erro/sucesso, e um error value, que pode ser usado para descrever ou detalhar o erro. Página 32/113
33 Figura 10: Formato do pacote SResvTear A mensagem SResvTear, figura 10, pode ser usada quer pelo router emissor quer por qualquer outro router ao longo do caminho. No primeiro caso é usada para terminar uma reserva explicitamente, no caso de esta deixar de ser necessária. Por sua vez, no segundo caso é usado em mudanças de rotas, para terminar a reserva em todos os routers que já não pertencem ao caminho. Valores usados para definir as mensagens Dado que foi necessário distinguir as mensagens utilizadas neste protocolo, das mensagens usadas pelo protocolo RSVP propriamente dito, foram empregues valores para o tipo de mensagem RSVP que estavam disponíveis, segundo o RFC2750. Deste modo, para tipo de mensagem RSVP, campo type do cabeçalho RSVP, foram usados os valores contidos na tabela 1. Já para a classe e tipo de objectos RSVP foram usados os valores representados na tabela 2, campos class e type de cada objecto RSVP respectivamente. Página 33/113
34 Tabela 1: Valores para os tipos de mensagens usados Tabela 2: Valores para a classe e tipo dos objectos usados Página 34/113
35 8.2 - Funcionamento do protocolo de sinalização Ao contrário do protocolo RSVP standard, o protocolo ora proposto é sempre da iniciativa do emissor. Figura 11: Funcionamento normal do protocolo de sinalização SRBQ Por conseguinte, tendo como base a figura11, ao iniciarmos uma reserva com a mensagem SResvInit (1), esta é enviada tendo como destino o IP de destino do luxo. Ao longo do processamento, a mensagem é capturada por todos os nós ao longo da rota, onde é feito o processamento da reserva, alocação de recursos no sistema e instalação do algoritmo de admissão. O nó seguinte, ao capturar a mensagem, dado que esta tem a opção Router_Alert, Página 35/113
36 envia uma nova mensagem baseada na anterior (2), mas com a informação relativa à rota e identificação do fluxo alteradas. Esta operação repete-se sucessivamente até a informação chegar ao receptor. Por sua vez, o nó final, destino da reserva, envia de volta para o nó de origem uma mensagem SResvStat (4) não só para determinar o sucesso da operação como também para confirmar a própria reserva. Desta feita, a mensagem é já enviada explicitamente de nó em nó ao longo do caminho anteriormente definido pela mensagem SResvInit. Este procedimento garante que, quando um nó cria a reserva para um determinado fluxo, todos os nós no sentido do nó de destino tenham as suas reservas feitas. Em cada nó, e para cada reserva, existe uma estrutura de dados relativa a cada reserva, que contém: A identificação do nó seguinte; A identificação da própria reserva (label); A identificação do nó anterior (b_label e f_label); A informação do IP do nó anterior e do nó seguinte. A estrutura supra descrita torna possível o envio de mensagens nó a nó (hop-byhop). É de salientar que cada reserva é identificada em cada nó por um label que representa a posição de memória em esta estrutura está, sendo assim possível aceder directamente à informação em questão e diminuir o custo de processamento em cada nó. Esta implementação exige que a identificação da reserva seja trocada em cada nó, pois o valor de label muda de nó em nó. Para tal quando um nó envia uma mensagem a outro nó, este, ao receber a mensagem, identifica a reserva através do label na mensagem. De seguida, o nó receptor faz o processamento da mensagem e, se necessitar de fazer o reenvio da mensagem para o nó seguinte, terá de consultar a informação relativa ao fluxo em questão e trocar o label para o label no nó seguinte bem como o IP de destino. Do mesmo modo, quando se tornar necessário enviar uma mensagem de erro/sucesso ao nó anterior, estes dois valores terão de ser enviados segundo o que está Página 36/113
37 guardado em memória para aquela reserva. Sendo forçoso terminar uma reserva, o nó emissor envia uma mensagem SResvTear ao nó seguinte (10). Este terá de retirar a reserva de recursos relativa ao fluxo em questão, trocar o valor do IP de destino da mensagem e do valor de identificação da mensagem segundo os valores guardados em memória e enviar a nova mensagem para o nó seguinte (11). Este processo repete-se até a mensagem chegar ao nó de destino. Figura 12: Funcionamento do protocolo de sinalização SRBQ num caso de existência de erro No entanto, durante o processo de refrescamento das reservas, podem ocorrer erros. Um dos erros que podem ocorrer é a inexistência da reserva num determinado nó. Nesta altura torna-se necessário enviar uma mensagem SResvStat, como representado na figura 12, para o nó de origem a informar a ocorrência. Sendo esta altura um momento de decisão, optamos por fazer o cancelamento da reserva. Porém, poderíamos iniciar de seguida uma outra reserva para colmatar a falha. O processo de refrescamentos das reservas inicia-se com o envio de uma mensagem de refrescamento. De seguida, todos os nós intermédios procedem ao refrescamento da reserva até a mensagem de refrescamento chegar ao nó em falha. Nesse momento, é enviado para a origem da reserva uma mensagem de status (3) para o nó anterior, no qual é feito o cancelamento da reserva. Página 37/113
38 origem. A mensagem é depois reenviada sucessivamente (4) até chegar ao router de Outro tipo de erros podem ocorrer quando existam, por algum motivo, mudanças de rotas. Nessa altura é necessário modificar todo o caminho da reserva. Neste processo, o emissor começa por enviar a mensagem de refrescamento, até esta chegar a um nó que não pertence ao caminho da reserva. Esta ocorrência pode facilmente ser detectada através da consulta do campo RSVP_Hop na mensagem e os dados em memória relativos à reserva. Se a mensagem chegar a um nó não pertencente ao caminho da reserva pode ocorrer uma das duas coisas: o label existe mas não pertence aquela reserva, ou o label não existe de todo. No primeiro caso, detecta-se no momento a mudança de rota porque o previous hop em memória é diferente. No segundo caso, só após enviar a mensagem de erro ao nó anterior é que é possível efectuar a detecção, através do next hop. Neste momento é inevitável enviar novas mensagens de SResvInit para criar um novo caminho para a reserva e actualizar todos os dados relativos à reserva, tentando terminar as reservas nos nós antigos. Todavia, em certos casos, tal pode não ser possível. O erro ora em análise deve ser evitado a todo o custo, visto que a detecção de mudanças de rota deve ser feita antes do envio da mensagem, através da consulta das tabelas de roteamento no próprio nó e a informação guardada na estrutura de dados da reserva. No caso de ser detectada uma mudança de rota, ao invés de ser enviada uma mensagem de refrescamento, deve-se proceder ao envio de uma mensagem SResvInit. Deste modo, define-se uma nova rota para a reserva e tenta-se, igualmente, terminar a reserva nos nós não usados. Ambos os métodos devem ser implementados, pois pode suceder que, dentro de certos circunstancialismos, no momento da consulta das tabelas de roteamento ainda não tenha ocorrido a mudança de rota. Neste processo os soft-states são cruciais, pois permitem uma maior flexibilidade em todo este processo. Com efeito, caso não seja possível terminar uma reserva nos nós Página 38/113
39 que deixaram de pertencer ao caminho da reserva, sabemos, e temos mesmo garantia, que estas vão ser terminadas por tempo. 9 Funcionamento do Deamon Foi implementado, em linguagem C, um deamon, com a finalidade de proceder à troca de mensagem da arquitectura RSVP. É da responsabilidade deste deamon iniciar as reservas a pedido da sua API, API esta que necessita de ser integrada na aplicação que pretende efectuar as reservas. Todo o processo de refrescamento é igualmente da competência deste deamon, bem como a detecção de erros na rede. O processo de terminação das reservas fica igualmente a cargo do deamon Funcionamento inicial e processador de pacotes A primeira tarefa a levar a cabo no âmbito deste o processo consiste em verificar que se o mesmo foi lançado como super-user, uma vez que certas funções implicam privilégios de root. Seguidamente, deve-se modificar a prioridade do processo, pois assim verifica-se uma melhoria substancial no rápido funcionamento do processo e consequentemente uma diminuição das perdas de pacotes (por saturação dos buffers de entrada). Para que seja possibilitar um correcto funcionamento do processador de pacotes, deve-se, primeiramente, identificar as interfaces disponíveis na máquina e correspondentes endereços IP e, posteriormente, configurar a rotina de serviço ao sinal SIGALRM. Neste momento, o processo fica num modo adormecido à espera de receber uma mensagem a fim de a processar. O processamento de pacotes baseia-se na identificação do pacote, através do tipo de pacote RSVP, contido no cabeçalho RSVP (ver tabela x). Para tal, é necessário averiguar se o pacote possui a opção Router_Alert activa a fim de destrinçar os pacotes SResvInit e SResvRefresh dos pacotes SResvStat e SResvTear. Todo o processo Página 39/113
40 seguinte fica, obviamente, dependente do tipo de pacote recebido. No caso de se tratar de um pacote SResvInit inicia-se uma nova reserva, e alocase memória para os dados da reserva. Concomitantemente, é guardado o IP do router anterior, o label, bem como toda a informação relativa às necessidades de recursos da reserva. Seguidamente é alterado o valor do label_setup e do RSVP_Hop e é feito o reenvio da mensagem para o router seguinte. Quando esta chegar ao seu destino final, é igualmente processada pelo router, como nos anteriores. No entanto, neste caso, não é feito o reenvio, mas antes o envio duma mensagem SResvStat para o router anterior. Quando o processador de pacotes recebe uma mensagem de SresvRefresh, o trabalho de deamon consiste em verificar a existência do label como reserva, através da consulta do mapa de memória alocada. Posteriormente, este remove a reserva temporal do fifo respectivo e volta a coloca-la no final do fifo com o novo tempo de expiração. Em caso de sucesso, é feito o reenvio do pacote para o router seguinte. Todavia, em caso de erro, é enviado para o router anterior uma mensagem SResvStat com o erro respectivo. No caso de receber uma mensagem SResvStat o deamon verifica a validade do label através do mapa de memória alocada e identifica se se trata de uma mensagem de sucesso ou de erro, através do campo error code. Em caso de sucesso o deamon procede à confirmação da reserva. Nesta situação, a reserva passa a ter disponíveis os recursos para o fluxo naquele router, sendo reenviada para o router seguinte, se necessário desde que anteriormente tenham sido alterados os valores do label, label_setup e RSVP_Hop. No caso de ser uma mensagem de erro a reserva é eliminada, uma vez que não foi implementado o processamento de mudanças de rota. Se o label da mensagem não existir no mapa de memória alocada é enviada um SResvStat a reportar o respectivo erro. Por último, no caso da mensagem recebida se tratar do tipo SResvTear é verificado a validade do label. Neste caso, a reserva temporal da memória é de igual modo removida Página 40/113
41 através do mapa de memória alocada. De seguida, toda a informação relativa à reserva é apagada, bem como alteradas as definições de controlo de tráfego. Se necessário, a este tipo de mensagem é reenviado para o router seguinte. Por fim, procede-se a uma nova procura da próxima reserva a expirar e activa-se o alarme para a próxima reserva a expirar. De salientar, que o processador de pacotes desliga este alarme inicialmente para que a função de serviço ao SIGALRM nunca seja executada, evitar, assim, eventuais incongruências. O socket usado para receber os pacotes é do tipo RAW, com filtro para mensagens RSVP e com a opção ROUTER_ALERT activa. Um fluxogama detalhado do funcionamento pode ser visto na figura 13. Página 41/113
42 Figura 13: Fluxograma do funcionamento do Deamon Página 42/113
43 9.2 - Funcionamento do módulo de comunicação com a API Este módulo, cujo fluxograma é representado pela figura 14, é lançado pelo programa principal como uma thread, o que, apesar do processamento paralelo, não afecta a performance do deamon, uma vez que, como supra referido, esta encontra-se maioritariamente num modo adormecido. Este modelo usa sockets do tipo UNIX e fica à espera de informação vinda da API, e procedendo ao respectivo processamento da informação. Após receber essa informação, verifica o que fazer com ela: apagar a reserva, criar reserva GS ou criar reserva AF. No caso de ser necessário criar uma reserva, é feito todo o procedimento de criação duma reserva, designadamente, reservar recursos o sistema, acrescentar à lista biligada toda a informação relativa à reserva, inserir o tempo de expiração na respectiva lista e enviar o pacote SResvInit. No final, o valor de label da reserva criada retorna à API. O valor de label da reserva criada vai ser usado quando for necessário terminar a reserva. A API fica assim com a vantagem de informar o deamon que quer terminar, fornecendo, para tal, o label. Esta possibilidade beneficia o processamento do deamon dado que possibilita o acesso directo à memória alocada para a reserva. O processo de apagar a reserva passa por retirar a reserva da tabela de tempo de expiração, apagar a informação sobre a reserva da lista biligada, alterar as definições de controlo de tráfego e enviar o pacote de SResvStat. Se a operação for bem sucedida é retornado à API o valor 0. Deve-se, porém, antes de apagar a reserva, verificar, através do mapa de memória alocada, a validade do label pois este pode já não existir. No final, a fim de evitar exclusão mútua, procede-se ao fecho do socket usado e programa-se a próxima reserva a expirar. Esta exclusão suceder visto que ambas as threads têm a possibilidade de aceder, em simultâneo, à memória global. Este módulo tem de ser executado com o mutex_lock, para garantir exclusão mútua no acesso a regiões de memória críticas. Página 43/113
44 Figura 14: Fluxograma do funcionamento do módulo de comunicação com a API Página 44/113
45 9.3 - Funcionamento da função manipuladora do SIGALRM Esta rotina de serviço é executada sempre que o kernel active a interrupção SIGALARM. Analisando o fluxograma da função, figura 15, podemos verificar que inicialmente, é levada a cabo uma procura em busca da próxima reserva a expirar. Caso a reserva tenha realmente expirado, este serviço cuida do seu tratamento. Caso não o efectue, o serviço programa o alarme para o seguinte tempo de expiração. O processo de tratamento passa por verificar se a reserva é local, isto é, se a reserva teve como origem a máquina em questão. Neste caso, tem de verificar se a reserva já foi confirmada, visto que é infrutífero proceder ao refrescamento da reserva se esta não foi confirmada. Em caso afirmativo, a reserva é removida da memória. No caso da reserva ter sido confirmada efectua-se, então, o refrescamento da reserva, enviando-se, de seguida, o pacote SResvRefresh para o router seguinte, de acordo com a informação guardada e memória. Este processo repete-se até encontrar uma reserva que não tenha expirado. É também exequível verificar a existência dum contador número de vezes. No presente projecto, este contador foi implementado para evitar o congestionamento dos buffers de recepção com mensagens de refrescamento. De facto, tal pode ocorrer quando existem muitas reservas em memória com tempos de expiração num intervalo de 1 segundo. Conseguimos, assim, dividir as mensagens de refrescamento em grupos de 100 espaçadas de 10ms, o que solucionou o problema. Contudo, entendemos que estes valores deveriam depender do número de reservas a refrescar e da capacidade de processamento dos próprios routers. Página 45/113
46 Start Procurar próxima reserva Próxima reserva expirou? Não Sim Numero vezes<100? Sim Programar temporizador para próxima reserva Não Sim A reserva não é local? Programar temporizador para 10ms Não Exit A reserva foi confirmada? Sim Não Remover reserva não local Remover resrva local Refrescar reserva local Enviar pacote SResvRefresh Procurar próxima reserva Incrementar número de vezes Figura 15: Fluxograma do funcionamento da função manipuladora do SIGALRM Página 46/113
47 9.4 - Funcionamento dos blocos principais Alguns dos blocos representados nos fluxogramas anteriores (figuras 13 a 15) deveram ser melhor explicados, pois o seu funcionamento não pode ser explicado visualmente Instalação do signal de controlo do SIGALRM Este bloco simplesmente programa a chamada da função sig_alarm (int) por parte do alarme do kernel, a fim de se proceder ao racionamento das expirações de reservas. Este inicia com a procura da reserva a expirar. De seguida, identifica o que fazer (remover reserva ou refrescar reserva) e programa o alarme para a próxima reserva (vide diagrama de blocos para a função manipuladora do SIGALRM) Receber pacote Este bloco é bloqueante, ou seja, enquanto não receber nenhum pacote está no modo adormecido (sleep), por isso não influencia o desempenho do deamon. Este recorre ao uso de sockets do tipo raw e verifica se o tamanho do pacote recebido corresponde ao tamanho do campo length do cabeçalho IP Criar reserva Para criar uma reserva é necessário reservar espaço em memória para a informação relativa à reserva, e colocar na lista bi-ligada circular de reservas. O tipo de reserva é colocado com -1 ou -2 para representar que a reserva não foi confirmada. Ao mesmo tempo, é alterado o mapa de bits de memória alocada, para uso da função Verify_label (union rsvdata*);, e guardada toda a informação conhecida até ao momento da reserva: label, label na máquina anterior, tos, port, rex, endereço IP na máquina anterior, endereço IP na própria máquina, e as características da reserva. Página 47/113
48 Criar reserva temporal Neste bloco é colocado, numa lista de tempos, o tempo no qual a reserva vai expirar, segundo o rex especificado para a reserva. Esta lista é, de facto, um array com 8 ponteiros, em que cada ponteiro associa-se para cada valor de rex possível. Por sua vez, cada fila de tempos encontra-se ordenada, estando no topo a próxima reserva a expirar ( First-In First-Out ). Deste modo, facilita-se o processo de procura da próxima reserva a expirar e, ao mesmo tempo, diminui-se o peso computacional Confirmar reserva Aqui a reserva é confirmada, ou seja, o tipo de reserva passa de -1 ou -2 para 1 ou 2 respectivamente. O 1 corresponde a uma reserva do tipo serviço garantido (GS) e o 2 o envio assegurado (AF) Programar próxima reserva Este bloco é fundamental visto que ocorre num momento em que já ocorreu uma das seguintes operações: criação de nova reserva, eliminação de uma reserva ou refrescamento de uma reserva. Posto isto, torna-se necessário: Averiguar quais as listas de tempos que expiraram; Averiguar quais as listas de tempos que sofreram alterações; Procurar a próxima reserva; Instalar o alarme para o tempo dessa mesma reserva. Página 48/113
49 Label válido? Este bloco é condicional visto que depende da existência do label como reserva na máquina em questão. Para averiguar a existência do mesmo, deve-se consultar um mapa de bits de memória alocada, e consoante o resultado retornar um valor boleano IP destino pertence a esta máquina? Este bloco é igualmente um bloco condicional uma vez que serve para verificar se a reserva tem como destino final a máquina em questão. O seu funcionamento depende do tipo de pacote e recorre a informação contida no próprio pacote quer nos dados em memória. Página 49/113
50 10 - Os Problemas Encontrados e as Soluções Propostas Durante a realização deste projecto vários problemas foram encontrados, problemas estes que poderiam ser a nível de implementação como a outros níveis. Todos eles foram solucionados como a seguir descrevemos Acesso a zonas de memória não alocadas Como supra explanado, no modelo ora apresentado cada reserva, para além de ser sofismaste, é representada através do endereço físico de memória em cada router, pelo que é imperativa a verificação do endereço de memória, sob pena de ocorrer um segmentation fault. A solução adoptada visou criar uma tabela de bits, em que cada bit representa uma posição de memória. Este processo implica o prévio alinhamento da memória alocada, pelo que cada label traduz-se num múltiplo da variável ALIGNMENT. O processo de verificação (int verify_label (union rsvdata*, union ubuffer*);) é bastante simples uma vez que apenas se socorre do uso de mascaras e comparações. Com efeito, o peso computacional deste processo é baixo Método de expiração de reservas (implementação dos soft-states ) O método de expiração de reservas foi implementado ao segundo e com tempos fixos. Ou seja, para a implementação do método ora em análise, foi criado um array de 8 ponteiros para listas ligadas de tempos, que corresponde aos possíveis valores do campo REX. Uma vez iniciada uma reserva, cada router verifica o valor deste campo e coloca no fim da lista de tempos para o devido valor de REX, o tempo no qual a reserva vai expirar, num método First-In Fisrt-Out. Deste modo, é garantido que a reserva no topo da lista é Página 50/113
51 a próxima a expirar. Para se aferir qual a próxima reserva a expirar é somente necessário consultar a primeira reserva em cada fila e verificar qual a que detém menor tempo. Posto isto, é activado um alarme (através do Kernel do Sistema Operativo) o qual vai expirar e activar a função correspondente a este sinal (void sig_alarm(int);). Esta implementação apresenta um problema próprio de implementação, dado observar-se uma concorrência entre o módulo de processamento de pacotes e o módulo de comunicação com a API, visto que não podem, em simultâneo, aceder a zonas de memória globais. Para obviar este problema recorreu-se ao uso de mutex's locks e em certas funções foi mesmo necessário desactivar o alarme e posteriormente voltar a activa-lo através da respectiva função (int next_resv_time();) Envio de pacotes SResvRefresh Neste item pretende-se analisar o processo de envio de pacotes, em especial, os problemas ocasionados de distribuição temporal do envio de pacotes. Uma vez que a base temporal implementada é ao segundo, e não ao milissegundo, ocorrem certos problemas de distribuição temporal no envio de pacotes (em especial, os pacotes SResvRefresh). Com efeito, e dado que num segundo podem ser refrescadas um grande número de reservas, os pacotes refresh acabam por ser enviados em massa. Ora, este facto pode conduzir à saturação dos buffers de entrada na máquina seguinte e consequente perda de pacotes, por a máquina ser incapaz de os processar. É de aquilatar que se tivéssemos pretendido implementar a base temporal ao milissegundo, teríamos de recorrer a time-ticks, o que poderia afectar irremediavelmente o peso computacional do modelo. Os pacotes de refrescamento são os principais responsáveis pelo aparecimento do problema supra explanado. Além disso, tal problema só ocorre em routers core com elevado número de reservas. Página 51/113
52 No que concerne ao número de reservas a partir do qual ocorrerem problemas de envio de pacotes de refrescamento, não nos é possível indicar um valor porque este factor depende da capacidade das máquinas em uso e da capacidade dos links usados. Para resolver este problema, poderíamos criar um escalonador de envio dos pacotes. Neste sistema, os pacotes seriam enviados para os routers core e debitados, segundo o destino e o número de reservas. Todavia, esta proposta não foi implementada pois entendemos que tem um peso computacional elevado. A solução adoptada, visando obstar a saturação dos buffers, dividiu o envio de pacotes de refrescamento em parcelas de 10ms. Por sua vez, cada parcela procede apenas ao envio de 100 pacotes. Não obstante a solução supra descrita tenha sido testada, e funcionado com êxito (solucionando o problema), estes valores podem revelar-se, em determinados casos, como insuficientes. A solução a adoptar seria, no nosso entendimento, variar quer as parcelas de segundo, quer o número de pacotes enviados por parcela, em valores em função do número de reservas. Todavia, tal proposta não foi implementada pois não era uma solução realizável a nível de testes Endereço de origem e identificação da reserva no router seguinte e anterior A arquitectura agora proposta exige que seja conhecido tanto o endereço de origem (em função do endereço de destino), como a identificação (label) da reserva no router (para o qual o pacote de sinalização vai ser enviado), pelo que se torna necessário criar métodos para obter estes mesmos valores. Com o intuito de descobrir o endereço de origem, isto é, o endereço do interface de rede pelo qual o pacote de sinalização vai ser enviado, construímos uma função (struct in_addr get_iface(struct in_addr);). Esta função permite a consulta do ficheiro com a Página 52/113
53 tabela de roteamento da máquina, que nos retorna o endereço IP do interface de rede pelo qual o pacote vai ser enviado. No que toca ao labels, o próprio modelo dispõe de mecanismos (através do campo label e do campo label_setup) que resolvem o problema agora em questão Comportamento hop by hop O modo de funcionamento do modelo agora em análise (envio de pacotes router a router, até ao destino final) impõe que a informação relativa a cada reserva seja processada em cada router ao longo do caminho (path), pelo que se torna necessário distinguir os vários tipos de pacotes de sinalização. Com vista à prossecução de tal resultado, ou seja, para que os pacotes de iniciação das reservas (SResvInit) sejam interceptados por todos os routers ao longo do path, torna-se necessário usar a opção ROUTER_ALERT (RFC 2113), que permite que todos os pacotes sejam interceptados pelos routers. Além disso, tal como os pacotes de refrescamento, os pacotes de iniciação têm igualmente a opção de ROUTER_ALERT activas, pois, deste modo, pode-se detectar mudanças nas tabelas de roteamento. Por seu turno, os pacotes de stat e teardown são enviados directamente para cada router no verdadeiro modo hop by hop, garantindo-se assim que são recebidos e processados pelos routers devidos Sincronização dos relógios dos computadores A sincronização dos relógios dos computadores é crucial para medir o atraso médio dos pacotes pois a ferramenta de teste usada baseia-se nesses mesmos relógios. Uma vez que a precisão dos relógios dos computadores é muito baixa foi necessário dotar os computadores de mais um link (Eth2) para sincronismo constante dos relógios Página 53/113
54 através do serviço Network Time Protocol (NTP), em que um dos computadores intervenientes serve de servidor NTP e o outro de cliente NTP. Este link de sincronismo baseia-se na tecnologia firewire (IEEE1394), tornando, por conseguinte, o sincronismo o mais rápido possível e, não ocupando largura de banda no link de teste. Para o cliente NTP não é necessário nenhuma configuração em especial, sendo apenas exigível usar a ferramenta 'ntpdate <server address>'. Todavia, este deve fazer constantemente o sincronismo através do script ntp_sync. Para o servidor NTP é necessário instalar o chrony-1.20 e correr o daemon chrony: 'chrony -f chrony.conf'. O ficheiro chrony.conf e o script ntp_sync são apresentados nos anexos Modificações feitas no pc para agir como um router A realização dos testes exigiu a utilização de computadores com vários interfaces de rede. O sistema operativo utilizado foi o Red Hat Fedora Core 3 com o kernel Este sistema operativo disponibiliza uma opção a nível do kernel para fazer o encaminhamento dos pacotes recebidos para o respectivo interface de rede, que, em seguida, segue o seu percurso. Esta opção, conhecida como IP Forwarding, encontra-se por defeito desligada. Para podermos usufruir desta opção é necessário recorrer ao comando sysctl, do seguinte modo: sysctl w net.ipv4.ip_forward= Erros possíveis de acontecer na rede e a sua solução Existem vários tipos de erros que podem ocorrer devido a problemas de rede, enquanto que outros são inerentes às próprias capacidades dos computadores utilizados, quer a nível de memória, a nível da capacidade de processamento ou da capacidade dos Página 54/113
55 interfaces de rede. Contudo, nem todos os erros são passíveis de serem solucionados. Certos erros terão mesmo de ser comunicados ao emissor para este decidir o que fazer. Nesta última solução, muito embora a operação habitual seja o terminus da reserva, é possível implementar outro tipo de solução. Uma das possíveis soluções seria terminar a reserva, comunicar ao emissor a fim de este iniciar nova reserva com os mesmos parâmetros. Como se torna óbvio, esta solução é manifestamente fácil de implementar Recursos insuficientes no interface de rede Este erro pode ocorrer sempre que é iniciada uma reserva, quando algum dos nós (pertencentes ao caminho que se iria criar) não dispõe de largura de banda suficiente aos requisitos da reserva, no interface necessário à reserva. Como solução para este erro, propomos o envio duma mensagem SResvStat a informar o emissor do sucedido Recursos insuficientes na alocação de memória Este erro é de ocorrência rara, pois este deamon usa, para cada reserva, muito pouca memória. Como acima mencionado, pressupondo que os computadores utilizados têm uma razoável quantidade de memória disponível, para simular este erro seria necessário não utilizar memória virtual ( memória swap ) e arranjar forma de ocupar memória desnecessariamente (consegue-se isso duma forma muito fácil, nomeadamente alocando memória desnecessariamente). Neste caso, a função de alocação de memória reporta um erro, que deve ser detectado pelo deamon e enviado uma mensagem SResvStat ao nó emissor Recursos insuficientes de processamento Página 55/113
56 Neste caso o erro não é directamente detectado. O único processo de o detectar cifra-se em recorrer ao refrescamento da própria reserva. Neste caso, as mensagem não são processadas pelo deamon atempadamente pelo que a reserva acaba por expirar devido à saturação do buffer de entrada (e consequente perda do pacote) ou, em alternativa, devido à escassez temporal de processamento para que a mensagem. Nesta situação é muito importante o uso do conceito de reservas soft-state, pois se a reserva não for refrescada, esta é terminada. Atente-se que o nó em questão ao receber um pacote de refrescamento deve ser capaz de verificar que a reserva deixou de existir (através do mapa de bits de memória alocada), e enviar uma mensagem SResvStat a todos os nós anteriores a reportar o erro sucedido. De igual modo, pode-se enviar uma mensagem de SResvTear para terminar a reserva a todos os nós seguintes. Esta última operação não é vital dado que as reservas sempre acabarão por expirar Mudanças de rota na rede Durante o tempo de vida duma reserva pode facilmente ocorrer mudanças no percurso do fluxo da reserva. Graças ao processo de envio de mensagens nó a nó ( hop by hop) é possível de detectar facilmente tais ocorrências. Através dos dados guardados em memória para cada reserva, onde se inclui, o IP do nó anterior e do nó seguinte, podemos fazer uma comparação desses valores com os valores contidos na própria mensagem. De notar que esta detecção deve-se fazer antes de enviar a própria mensagem. Para realizar tal tarefa, deve-se consultar a tabela de roteamento no nó em questão e verificar se esta vai ser enviada pelo interface correcto. Detectado o problema pode-se recorrer a um mecanismo de mudança da rota da reserva. Este mecanismo consiste em detectar a mudança de rota e seguidamente tentar criar novas reservas com as mesmas especificações pelo novo percurso. Ou seja, enviase uma mensagem SResvInit a partir do nó onde foi detectado o erro e procede-se a um processo de criação de reserva em tudo idêntico ao inicial. Página 56/113
57 Pode-se, igualmente, terminar as reservas anteriores através do envio duma mensagem SResvTear. Contudo, se tal não for possível, e visto que a reserva acaba por terminar por falta de refrescamento, este problema não merece especial atenção. O erro pode ser detectado no nó seguinte ao da mudança de rota, quando, na altura da consulta da tabela de roteamento do nó, a mudança ainda não tivesse ocorrido, mas já tenha sucedido (essa mudança) aquando envio da mensagem. Neste caso o nó vai detectar a reserva como se fosse uma reserva que tivesse terminado. A solução para este problema passaria por enviar uma mensagem SResvStat ao nó anterior, como se de uma reserva expirada se tratasse. Esta, por sua vez, detectaria que ainda possuía a reserva em memória e procederia à criação dum novo caminho para a reserva. Muitos outros erros podem ocorrer. Contudo, uma vez que tratando-se duma arquitectura que recorre ao uso de soft-timers, que garante a extinção das reservas, o principal problema a garantir traduz-se em assegurar a utilidade e bom funcionamento do protocolo no caso da reserva se extinguir. O método que melhor se afigura para prosseguir tal intento, será desenvolver mecanismos de informação ao emissor da reserva para que este decida o que fazer. Página 57/113
58 11 - Biblioteca de comunicação com o deamon (API) Foi desenvolvida uma biblioteca (API), para facilitar a comunicação dos processos, que necessitam dos recursos, com o deamon. Esta biblioteca dispõe de apenas uma função, que permite a criação de reservas, (do tipo serviço garantido (GS) e do tipo envio assegurado (AF)) bem como a terminação das mesmas. Nesta biblioteca recorreu-se ao uso de sockets UNIX, os quais permitem um elo de comunicação entre as duas unidades. De salientar, que o valor retornado pela função corresponde ao label da reserva, no nó emissor, tendo este de ser utilizado para a terminação da mesma. Para facilitar a detecção de problemas com a aplicação, é enviado o PID da aplicação (Número identificador do processo) a fim de facilitar ao deamon a verificação se realmente é necessário continuar o processo de refrescamento das reservas, ou se, por outro lado, e no caso da aplicação terminar repentinamente, terminar com as respectivas reservas. Contudo, e apesar deste mecanismo ser transparente para o utilizador, é necessário ter o cuidado de lançar o pedido de reserva a partir dum processo que se mantenha em memória de execução durante o tempo em que a reserva é necessária Modo de utilização da API A utilização é de facto bastante simples, sendo necessário apenas o uso de uma função disponibilizada pela biblioteca. Inicialmente é necessário instalar a biblioteca no sistema, bem como o seu header. Seguidamente, é só invocar a função segundo o seu modo de utilização. Utilização: unsigned int comm_rsvp_api(int type, char tos, int rex, int port, char *daddr, long opt1, long Página 58/113
59 opt2, long opt3); O campo type representa o tipo de reserva a criar. No caso duma reserva de serviço garantido este valor será 1, para o caso duma reserva de envio assegurado será de 2. Para terminar uma reserva o valor a enviar será o retornado pela mesma função na altura da criação da reserva. O campo tos representa o valor para o type of service da reserva e terá de ser um valor entre 0 e 255 de acordo com o tipo de reserva a efectuar. De notar que a biblioteca não faz qualquer verificação deste valor. Port será a porta de destino do fluxo pretendido, enquanto o ponteiro daddr será o endereço de destino no formato de string (Ex: ). Além disso, existem mais três campos (opt1, opt2 e opt3), que serão usados consoante o tipo de reserva. No caso duma reserva de serviço garantido apenas os dois primeiros serão usados, e serão o valor do tamanho do tocken bucket e a taxa do mesmo respectivamente. Por outro lado, se a reserva for do tipo envio garantido, serão necessários os três campos, em que os dois primeiros são as taxas de degradação e a ultima a taxa de perdas. Exemplo de utilização: #include <srbq.h> //cria uma reserva do tipo GS durante 1000 segundos e de seguida apaga essa mesma reserva int main( int argc, char **argv ) Int ret; //criar reserva GS if((ret=comm_rsvp_api(1, 20, 5, 1000, , , 1000, 0))>0) printf("reservation Success:%d\n",(unsigned int) ret); Página 59/113
60 else printf("reservation failed\n"); sleep (1000); //aguardar 10 segundos comm_rsvp_api(ret,0,0,0,0,0,0,0); //apagar reserva ; exit(0); Página 60/113
61 12 - Testes realizados 12.1 Teste ao modelo de controlo de tráfego Figura 16: Configuração para modelo de teste do controlo de tráfego O presente modelo foi testado através de uma ferramenta de geração de tráfego com a possibilidade de modificação do TOS ( RUDE versão 0.62). Os testes iniciais foram desenvolvidos no sentido testar a funcionalidade do modelo de forma a averiguar se todos os tipos de serviços estavam ou não a ser encaminhados para a respectiva disciplina. Para o efeito, usando-se tão só um interface lo (loopback), gerou-se, individualmente, pacotes com os diferentes TOS. Ou seja, no modelo ora apresentado não foi utilizada qualquer rede de computadores. No final, conclui-se pela correcta funcionalidade do modelo. Todavia, a verdadeira pretensão deste trabalho consistiu em criar uma simulação em que fosse possível gerar vários fluxos simultâneos com diferentes taxas de transmissão de modo a medir as taxas efectivas, atrasos, perdas, jitter, etc. a serem registadas através de um script para o RUDE. O presente projecto foi desenvolvido partindo do princípio que o fundamental para o modelo seria garantir que os pacotes GS eram tratados com a máxima de prioridade até uma dada taxa de transferência, a partir da qual o modelo poderia descartar pacotes. A configuração de teste usada, figura 16, foi a mais simples que se pode criar, tratando-se apenas duma ligação ponto a ponto por onde serão gerados os fluxos de teste. Também recorremos ao uso de um outro interface para sincronismo dos relógios das máquinas através do NTP (Network Time Protocol). Esta explicação pode ser encontrada na secção Página 61/113
62 12.1 Teste ao funcionamento do protocolo de sinalização Para testar o protocolo de sinalização foi necessário implementar um deamon que suportasse todo o protocolo desenvolvido. Este protocolo deve ser capaz de criar reservas conforme os parâmetros pedidos, guardar toda a informação relevante à reserva em memória e proceder aos refrescamentos necessários. Este processo deverá ser capaz de suportar um número real de reservas, o que poderá ser bastante elevado se estivermos a falar de routers core e ao mesmo tempo com o mínimo de perdas de pacotes de sinalização. Tal teste apenas só foi possível de realizar na ausência dos ditos fluxos da reserva, pois os interfaces disponíveis não são capazes de suportar tamanho número de pacotes ao mesmo tempo no interface, pois poderia ocorrer o enchimento do buffer de recepção nas máquinas utilizadas a consequente perda de pacotes. Como já foi explicado nos problemas encontrados. Figura 17: Configuração do modelo de teste do protocolo A montagem utilizada, figura 17, tem de ser capaz de simular uma ligação ponto a ponto, entre o emissor e o receptor do fluxo, deve ser igualmente capaz de simular avarias na rede, para simular as mudanças de rotas e destinos inatingíveis. Cada máquina será então considerada um nó, o qual simula a interligação entre redes, sendo possível, usar num máximo de quatro nós para realizar o percurso entre o emissor e o receptor. Página 62/113
63 13 - Resultados obtidos Modelo de controlo de tráfego Nestes testes realizados usou-se como TC Script 3 o script apresentado e como default um pfifo_fast: bands 3 priomap (implementado por defeito pelo kernel). Script de teste 1 #rude script START NOW #FLOW 1 ID=10 TOS=0xb0 GS #FLOW 2 ID=20 TOS=0x2e Sig #FLOW 3 ID=30 TOS=0x88 AF1 #FLOW 4 ID=40 TOS=0x90 AF2 #FLOW 5 ID=50 TOS=0x98 AF3 #FLOW 6 ID=60 TOS=0x30 BE #GS ON :10010 CONSTANT TOS xb0 #Sig ON :10010 CONSTANT TOS x2e #AF ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x98 #BE ON :10010 CONSTANT TOS x OFF OFF OFF OFF OFF OFF Página 63/113
64 Default TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,909 0,820 8, ,31% Sig 0x2E ,865 6,413 36, ,50% AF1 0x ,417 1,207 39, ,58% AF2 0x ,936 0,507 12, ,32% AF3 0x ,319 0,895 23, ,48% BE 0x ,915 0,123 12, ,32% Total LB TC Script 3 TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,378 0,090 2, ,00% Sig 0x2E ,516 0,337 4, ,00% AF1 0x ,416 0,095 4, ,00% AF2 0x ,397 0,106 4, ,00% AF3 0x ,415 0,115 4, ,00% BE 0x ,036 0,098 9, ,52% Total LB Tabela 3: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 1º teste Neste teste inicial, é possível observar não só o correcto funcionamento do script, mas também a ausência de pacotes perdidos quer em GS, em Sig e em AFx. Um dos problemas detectados nesta fase, problema este comum a todos os outros testes, encontra-se na taxa recebida, onde se pode verificar um valor superior ao enviado. Este problema prende-se com o facto da ferramenta de recepção utilizada medir os valores temporais do primeiro pacote recebido e do último para calcular a taxa recebida. Ou seja, a janela temporal de medição no receptor é sempre inferior à janela temporal do emissor, já que este baseia-se nos tempos impostos pelo script (10s no exemplo utilizado). No que concerne aos pacotes perdidos, estes apenas existem em BE. Este facto relaciona-se com o funcionamento do próprio script, uma vez que BE tem a menor prioridade. Ora, como é fácil de compreender, tal característica implica uma maior probabilidade de ocorrência de pacotes perdidos. Relembra-se que esta perda ocorre simplesmente devido à necessidade de isto garantir o correcto funcionamento das filas com maior prioridade. Página 64/113
65 É evidente o melhoramento em todos os valores medidos, visto que o que se pretende é garantir os recursos para tráfego multimédia. Pode-se constatar que o atraso e o jitter em BE e AF formam melhorados. Script de teste 2 #rude script START NOW #FLOW 1 ID=10 TOS=0xb0 GS #FLOW 2 ID=20 TOS=0x2e Sig #FLOW 3 ID=30 TOS=0x88 AF1 #FLOW 4 ID=40 TOS=0x90 AF2 #FLOW 5 ID=50 TOS=0x98 AF3 #FLOW 6 ID=60 TOS=0x30 BE #GS ON :10010 CONSTANT TOS xb0 #Sig ON :10010 CONSTANT TOS x2e #AF ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x98 #BE ON :10010 CONSTANT TOS x OFF OFF OFF OFF OFF OFF Página 65/113
66 default TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,739 0,972 5, ,00% Sig 0x2E , , , ,14% AF1 0x , , , ,81% AF2 0x ,728 0,121 4, ,00% AF3 0x ,424 4,125 98, ,06% BE 0x ,768 0,081 5, ,00% Total LB TC Script 3 TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,383 0,081 2, ,00% Sig 0x2E ,426 0,129 5, ,00% AF1 0x ,437 0,118 11, ,00% AF2 0x ,419 0,089 5, ,08% AF3 0x ,506 0,114 5, ,08% BE 0x ,572 0,126 7, ,46% Total LB Tabela 4: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 2º teste Nesta configuração de teste pretende-se testar o correcto funcionamento das filas AF, em que AF1 está com um débito normal e, AF2 e AF3 estão com um débito superior ao policiado pelo script. É possível verificar a limitação de largura de banda de 10Mbps e a consequente perda de pacotes. Neste caso, os valores do atraso e jitter também foram melhorados para BE e AF. Além disso, verifica-se que em 'default' a fila AF2 não tem perdas. Este facto devese ao pfifo_fast implementado pelo kernel. Este prioriza os pacotes segundo o ToS, e, neste caso, encaminha os pacotes com o ToS=0x80 para a banda 0. O mesmo procedimento sucede no que toca ao BE. A explicação deste facto pode ser encontrada em AEN659. Página 66/113
67 Script de teste 3 #rude script START NOW #FLOW 1 ID=10 TOS=0xb0 GS #FLOW 2 ID=20 TOS=0x2e Sig #FLOW 3 ID=30 TOS=0x88 AF1 #FLOW 4 ID=40 TOS=0x90 AF2 #FLOW 5 ID=50 TOS=0x98 AF3 #FLOW 6 ID=60 TOS=0x30 BE #GS ON :10010 CONSTANT TOS xb0 #Sig ON :10010 CONSTANT TOS x2e #AF ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x98 #BE ON :10010 CONSTANT TOS x OFF OFF OFF OFF OFF OFF Default TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,046 1,070 9, ,15% Sig 0x2E , , , ,00% AF1 0x ,187 78, , ,96% AF2 0x ,988 0,140 9, ,17% AF3 0x ,754 3, , ,96% BE 0x ,026 0,089 9, ,58% Total LB TC Script 3 TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,388 0,094 8, ,00% Sig 0x2E ,388 0,058 0, ,00% AF1 0x ,430 0,099 8, ,07% AF2 0x ,513 0,120 7, ,08% AF3 0x ,463 0,146 7, ,02% BE 0x ,582 0,124 9, ,02% Total LB Tabela 5: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 3º teste Página 67/113
68 Esta configuração é em tudo idêntica à anterior, apenas passa a ser AF3 a ter um débito 'normal' e AF1 e AF2 um débito acima dos 10Mbps. As conclusões são idênticas às da configuração anterior. Script de teste 4 #rude script START NOW #FLOW 1 ID=10 TOS=0xb0 GS #FLOW 2 ID=20 TOS=0x2e Sig #FLOW 3 ID=30 TOS=0x88 AF1 #FLOW 4 ID=40 TOS=0x90 AF2 #FLOW 5 ID=50 TOS=0x98 AF3 #FLOW 6 ID=60 TOS=0x30 BE #GS ON :10010 CONSTANT TOS xb0 #Sig ON :10010 CONSTANT TOS x2e #AF ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x98 #BE ON :10010 CONSTANT TOS x OFF OFF OFF OFF OFF OFF Página 68/113
69 Default TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,858 0,621 13, ,61% Sig 0x2E ,463 7,816 98, ,00% AF1 0x ,749 1, , ,14% AF2 0x ,839 0,343 14, ,34% AF3 0x ,853 0,828 46, ,35% BE 0x ,800 0,097 14, ,55% Total LB TC Script 3 TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,720 3,389 23, ,05% Sig 0x2E ,510 0,289 10, ,00% AF1 0x ,467 0,139 10, ,08% AF2 0x ,449 0,150 10, ,08% AF3 0x ,466 0,157 10, ,08% BE 0x ,203 0,105 21, ,39% Total LB Tabela 6: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 4º teste Esta configuração visa testar a limitação de largura de banda reservada para GS. Neste caso, verifica-se o corte na taxa definida (256kbit) e a consequente perda de pacotes. O valor do atraso aumentou consideravelmente, pelo que se pode entender que a reserva de largura de banda deve ser sempre superior à taxa pretendida pela aplicação. No caso contrário torna-se impossível garantir o correcto funcionamento da aplicação. Script de teste 5 #rude script START NOW #FLOW 1 ID=10 TOS=0xb0 GS #FLOW 2 ID=20 TOS=0x2e Sig #FLOW 3 ID=30 TOS=0x88 AF1 #FLOW 4 ID=40 TOS=0x90 AF2 #FLOW 5 ID=50 TOS=0x98 AF3 #FLOW 6 ID=60 TOS=0x30 BE #GS ON :10010 CONSTANT TOS xb0 #Sig ON :10010 CONSTANT TOS x2e #AF1 Página 69/113
70 ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x ON :10010 CONSTANT TOS x98 #BE ON :10010 CONSTANT TOS x OFF OFF OFF OFF OFF OFF Default TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,923 0,554 8, ,40% Sig 0x2E , , , ,63% AF1 0x , , , ,82% AF2 0x ,975 0,231 9, ,22% AF3 0x , , , ,98% BE 0x ,911 0,089 10, ,19% Total LB TC Script 3 TOS Taxa Enviada (bps) Taxa Recebida (bps) Atraso (mseg) Jitter (mseg) Jitter Max (mseg) Pacotes Enviados Pacotes Recebidos Pacotes Perdidos % Pacotes Perdidos GS 0xB ,389 0,104 5, ,00% Sig 0x2E ,398 0,090 2, ,00% AF1 0x ,460 0,098 5, ,21% AF2 0x ,444 0,115 4, ,22% AF3 0x ,434 0,106 5, ,32% BE 0x ,704 0,176 40, ,84% Total LB Tabela 7: Resultados obtido com modelo de controlo de tráfego vs sem modelo de controlo de tráfego 5º teste No nosso entendimento, esta última configuração de teste é a mais premente dado que se propõe simular uma rede congestionada com uma reserva de 256kbits para uma aplicação multimédia e verificar se os valores do atraso e do jitter são inferiores aos valores teóricos (atraso <= 100ms). Temos então AF1, AF2, AF3 e BE saturadas num total de 170Mbps a serem transmitidos para a rede (100Mbps). Nesta observamos a consequente perda de pacotes em AFx e BE para que em GS e Sig. existia garantia de valores mínimos no atraso, jitter e perda de pacotes. Os resultados obtidos verificam o correcto funcionamento do script. Página 70/113
71 13.1 Protocolo de sinalização Os resultados obtidos para o protocolo de sinalização foram somente relativos ao seu desempenho, quer a nível do correcto funcionamento, quer a nível do desempenho a nível de processador. De notar que os resultados obtidos são relativos ao um router core que neste caso, e para sabermos a relação de escala, foi um Pentium II a 266MHz. Os dados obtidos referem-se apenas ao processo em estudo. Número de reservas Ocupação do CPU % ,70% ,17% ,00% ,70% ,00% ,00% ,00% ,70% ,30% ,00% ,00% ,60% Tabela 8: Resultados obtidos para o desempenho do protocolo de sinalização em função do processamento Página 71/113
72 14 Soluções inacabadas Um dos objectivos que não foi alcançado, foi a integração do modelo de controlo de tráfego, cuja implementação se baseia no uso da biblioteca LTCMMM, com o Deamon. Foi inicialmente criado um script ( tcscript.h ) baseado nesta biblioteca para efectuar as configurações iniciais do modelo de tráfego. Tal não resultou, pois a nível do policiamento, foram encontrados problemas, os quais não conseguimos resolver nem explicar. Contudo, e se for algum dia possível resolver este problema, todo o processo de alteração dos parâmetros do modelo torna-se bastante simples, pois, como já dissemos, este modelo de tráfego baseia-se na soma dos parâmetros dos vários fluxos, sendo então necessário apenas alterar esses parâmetros com o LTCMMM. Este objectivo já é possível e foi testado. Um outro problema que não foi resolvido, foi informar a aplicação que requisitou os recursos quando acontecer, por algum erro na rede, que a reserva foi terminada. Foi pensado enviar um signal à própria aplicação, já que o deamon conhece o seu PID, mas tal não foi implementado. Página 72/113
73 15 - Conclusões Como já foi explicado na secção anterior, nem todo os objectivos que nos propusemos alcançar foram conseguidos, nomeadamente o objectivo final. Este objectivo consistiria em combinar o modelo de tráfego com o protocolo de sinalização, contudo tal não foi possível, quer a nível de tempo, quer a nível de alguns problemas encontrados, a nível de implementação, com a biblioteca LTCMMM. Estes problemas seriam facilmente ultrapassados com ligeiras correcções no seu código e mais alguns testes Modelo de controlo de tráfego Da análise das tabelas com os resultados dos testes, e de um modo geral, podemos concluir pelo correcto funcionamento do script desenvolvido, designadamente, pela observação das diferenças, para os vários casos, entre o default (controlo de tráfego por defeito do linux pfifo-fast) e o nosso script para implementação de QoS. Além disso, podemos verificar a garantia de largura de banda, o atraso mínimo e jitter mínimo para a classe GS até à largura de banda definida no script para o token bucket do GS, a partir da qual se pode verificar a perda de pacotes. Podemos igualmente observar, através do atraso, que a prioridade desta classe é superior a todas as outras classes. Na classe de sinalização, também definida por um token bucket, mas com uma taxa inferior, pode-se assistir a um comportamento idêntico ao da classe GS no que concerne à garantia de largura de banda, ao atraso mínimo e ao jitter mínimo até à taxa definida, após a qual começa a perder pacotes. Nas classes AF podemos testemunhar a limitação de largura de banda nos 10Mbits e inferioridade da sua prioridade quer à BE, quer à Sig. A classe BE, é neste caso, a 'pior das classes', com a menor prioridade, logo sujeita a maiores atrasos, maiores valores de jitter e a maior perda de pacotes, podendo mesmo atingir quase os 100% numa situação de elevado congestionamento do link de teste. Podemos verificar as diferenças comparando os resultados entre o default (controlo Página 73/113
74 de tráfego por defeito do linux pfifo-fast) e o nosso script para implementação de QoS. Do exposto resulta, que o projecto desenvolvido logrou criar melhorias em termos de garantias de largura de banda, atraso e jitter, condições essenciais para aplicações multimédia, muito embora possam ocorrer, esporadicamente, perdas de pacotes. Para obviar a esta limitação, pode-se considerar um meio para atingir um certo objectivo Protocolo de sinalização O protocolo de sinalização efectuou o compromisso que se desejava, chegando mesmo a conseguir reservas ao mesmo tempo num só nó e através de um só interface de rede. Foi possível detectar falhas na rede, quer a nível de mudanças de rota, quer a nível de quebra de ligação ou até a falhas no envio dos pacotes de refrescamento e consequente expiração da reserva. Não foram obtidos mais resultados, pois era de esperar conseguir integrar o módulo de controlo de tráfego com o deamon, tal não foi conseguido, mas seria de esperar o correcto funcionamento do deamon. Página 74/113
75 15 - Bibliografia Quality of Service (QoS) Linux Advanced Routing & Traffic Control HOWTO Qualidade de Serviço em Redes de Comutação de Pacotes, Rui Pedro de Magalhães Prior, Março 2001 End-to-End QoS with Scalable Reservations, Rui Prior, Susana Sargento, Sérgio Crisóstomo, Pedro Brandão, Julho 2003 Evaluation and Analysis of the Scalable Reservation-Based, Rui Prior, Susana Sargento, Pedro Brandão, Sérgio Crisóstomo, Fevereiro 2004 Unix Network Programmng, Network APIs: Socket and XTI, W. Richard Stevens, Second Edition Unix Network Programmng, Interprocess Comunications, W. Richard Stevens, Second Edition RSVP, Reservation Protocol, RFC 2205, Resource ReServation Protocol RFC 2113, IP Router Alert Option RFC 2207, RSVP Extensions for IPSEC Data Flows RFC 2210, The use of RSVP with IETF Integrated Services RFC 2474, Definition of the Differentiated Service Field in the IPv4 and IPv6 Headers RFC 2475, An Architecture for Differentiated Service RFC 2750, RSVP Extensions for Policy Control LTCM, a Linux QoS API Library, Página 75/113
76 16 - Agradecimentos - À Professora Doutora Susana Sargento e ao Professor Rui Prior pela orientação, colaboração e tempo disponibilizado durante a realização deste projecto. - Ao nosso colega Hugo Santos pela sua disponibilidade e atenção em relação ao uso da biblioteca LTCMMM. - A nossa colega Sara Pinto pela ajuda dada na correcção dos textos produzidos para este documento e pelas ideias gráficas para a página e poster. - A todos os colegas, amigos e familiares que nos ajudaram quer com a troca de ideias e métodos para a realização do projecto, quer com o apoio e incentivo dado. A todos o nosso agradecimento e reconhecimento. Página 76/113
77 17 - Anexos Tcscript3 DEV=eth0 LINKCAP=100Mbit GSRATE=1Mbit GSLIMIT=32000 GSBURST=16000 SIGRATE=256kbit SIGLIMIT=7500 SIGBURST=3750 AFLIMIT=60KB AFMIN=15KB AFMAX=45KB AFBURST=20 AFPROB1=0.01 AFPROB2=0.02 AFPROB3=0.03 AF1RATE=10Mbit AF2RATE=10Mbit AF3RATE=10Mbit AVPKT=1540 MTU=1514 MPU=48 case "$1" in stop) #Apagar ifconfigtodas as configurações anteriores tc qdisc del dev $DEV root echo "All settings deleted" ;; start) echo "Installing settings..." #Adicionar dsmark na raiz tc qdisc add dev $DEV root handle 1:0 dsmark indices 64 set_tc_index default_index 1 #Adicionar qdisc principal tipo PRIO tc qdisc add dev $DEV parent 1:0 handle 2:0 prio bands 4 #Adicionar fila tipo token bucket na banda 1 GS tc qdisc add dev $DEV parent 2:1 handle 21:0 tbf limit $GSLIMIT rate $GSRATE burst $GSBURST mtu $MTU #Signal tc qdisc add dev $DEV parent 2:2 handle 22:0 tbf limit $SIGLIMIT rate $SIGRATE burst $SIGBURST mtu $MTU #Adicionar AF tc qdisc add dev $DEV parent 2:3 handle 23:0 gred setup DPs 3 default 3 grio tc qdisc change dev $DEV parent 2:3 handle 23:0 gred limit $AFLIMIT min $AFMIN max $AFMAX avpkt $AVPKT burst $AFBURST bandwidth $LINKCAP DP 1 probability $AFPROB1 prio 2 tc qdisc change dev $DEV parent 2:3 handle 23:0 gred limit $AFLIMIT min $AFMIN max $AFMAX avpkt $AVPKT burst $AFBURST bandwidth $LINKCAP DP 2 probability $AFPROB2 prio 3 tc qdisc change dev $DEV parent 2:3 handle 23:0 gred limit $AFLIMIT min $AFMIN max $AFMAX avpkt $AVPKT burst $AFBURST bandwidth $LINKCAP DP 3 probability $AFPROB3 prio 4 #BE tc qdisc add dev $DEV parent 2:4 handle 24:0 pfifo limit $AVPKT #Filtros #GS TOS=0xb0 tc filter add dev $DEV parent 1:0 protocol ip pref 1 tcindex mask 0xfc shift 2 pass_on tc filter add dev $DEV parent 1:0 protocol ip pref 1 handle 0x2c tcindex classid 1:10 #Sig TOS=0x2e Página 77/113
78 #AF TOS=0x88 0x90 0x98 tc filter add dev $DEV parent 1:0 protocol ip pref 2 tcindex mask 0xfc shift 2 pass_on tc filter add dev $DEV parent 1:0 protocol ip pref 2 handle 0x22 tcindex classid 1:31 police rate $AF1RATE burst 256k mtu $MTU drop tc filter add dev $DEV parent 1:0 protocol ip pref 2 handle 0x24 tcindex classid 1:32 police rate $AF2RATE burst 256k mtu $MTU drop tc filter add dev $DEV parent 1:0 protocol ip pref 2 handle 0x26 tcindex classid 1:33 police rate $AF3RATE burst 256k mtu $MTU drop #Atribuicao classe #GS tc filter add dev $DEV parent 2:0 protocol ip pref 1 tcindex mask 0xf0 shift 4 pass_on tc filter add dev $DEV parent 2:0 protocol ip pref 1 handle 0x1 tcindex classid 2:1 #AF tc filter add dev $DEV parent 2:0 protocol ip pref 2 tcindex mask 0xf0 shift 4 pass_on tc filter add dev $DEV parent 2:0 protocol ip pref 2 handle 0x3 tcindex classid 2:3 #Signal (RSVP=0x2e) tc filter add dev $DEV parent 2:0 protocol ip prio 3 u32 match ip tos 0x2e 0xff flowid 2:2 #BE tc filter add dev $DEV parent 2:0 protocol ip prio 4 u32 match ip tos 0x00 0x00 flowid 2:4 echo "All settings installed." ;; show) echo "Qdisc:" tc qdisc show dev $DEV echo "Filters:" tc filter show dev $DEV parent 1: tc filter show dev $DEV parent 2: echo "Classes:" tc class show dev $DEV parent 1: tc class show dev $DEV parent 2: ;; restart) echo "Restarting script..."./$0 stop./$0 start ;; *) echo echo "Usage: "$0" start stop show restart" echo "options:" echo " stop - clear all settings (kernel default)" echo " start - install all settings" echo " show - view all settings" echo " restart - restart settings" echo esac ntp_sync while ((1)) do ntpdate done Página 78/113
79 chrony.conf driftfile /etc/chrony.drift commandkey 25 keyfile /etc/chrony.keys initstepslew 10 client1 client3 client6 local stratum 8 manual allow RSVPD.cpp /*************************************************************************** * Copyright (C) 2005 by / * * [email protected] / [email protected] * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA , USA. * ***************************************************************************/ //#include <iostream> //#include <cstdlib> #include "rsvpd.h" using namespace std; // RSVPD // Resource ReserVation Protocol Deamon int ifnum; struct if_names ifnames[num_ifaces]; struct if_stat ifstat[num_ifaces]; union rsvdata *resvinit; struct rsvtime *resvtime[8]; struct rsvtime *endresvtime[8]; unsigned int resvtimenum[8]; int resvnum; pthread_mutex_t mutex; struct rsvtime next_exp_time; int timetoexp; int no_next_exp; int rsock; struct itimerval time_new, time_old; union rsvdata *map_start, *map_end; char *bitmap; int num_map_var; int main(int argc, char *argv[]) int ra, i; struct sockaddr_in *saptr=null; struct ifreq ifreq; struct if_nameindex *iflist=null, *iflist_init=null; union ubuffer bufferin; union rsvdata *resp; struct in_addr addr, addr2; pthread_t pthread_api; Página 79/113
80 // qdisc *root; // dsmark_qdisc dsmarkqd(64); // prio_qdisc prioqd(4, priomap); // tbf_qdisc tbf_gs; // tbf_qdisc tbf_sig; // gred_qdisc gredqd; // fifo_qdisc fifo_be(fifo_qdisc::pfifo,1000); printf("srbq RSVP Reservation Daemon\n"); printf(" \n"); // verificar se o daemon foi lanã ado como super-user if (getuid()!=0) printf("please run this daemon as root\naborting\n"); exit(1); // alteraã Ã o da prioridade do processo nice (-10); // colocar todas os fifos de reserva a zero e definiã Ã o de valores iniciais for (i=0; i<8; i++) resvtime[i]=0; resvtimenum[i]=0; no_next_exp=0; timetoexp=0; num_map_var=0; // instalar signals ************************************************************************* signal(sigalrm, sig_alarm); // fazer abertura do socket do tipo RAW if((rsock = socket(af_inet, SOCK_RAW, IPPROTO_RSVP)) < 0) printf("socket error %s\n",strerror(errno)); return(-1); if((setsockopt(rsock, IPPROTO_IP, IP_ROUTER_ALERT, &ra, sizeof(ra))) < 0) close(rsock); return (-1); // identificar ip's do router *************************************************************** ifnum=0; for(iflist_init=iflist=if_nameindex(); iflist->if_name!=null; iflist++) strncpy(ifreq.ifr_name, iflist->if_name, IF_NAMESIZE); saptr=(struct sockaddr_in *)&ifreq.ifr_addr; if(ioctl(rsock, SIOCGIFADDR, &ifreq)==0) strncpy(ifnames[ifnum].name, ifreq.ifr_name, IF_NAMESIZE); ifnames[ifnum].addr=saptr->sin_addr; printf("%-5s :: %s\n", ifnames[ifnum].name, inet_ntoa(ifnames[ifnum].addr)); strncpy(ifstat[ifnum].name, ifreq.ifr_name, IF_NAMESIZE); ifstat[ifnum].addr=ifnames[ifnum].addr; ifstat[ifnum].stbr=0; //colocar valores por defeito ifstat[ifnum].stbs=0; //colocar valores por defeito ifstat[ifnum].sdrt=0; //colocar valores por defeito ifstat[ifnum].sdrt2=0; //colocar valores por defeito ifstat[ifnum].sdrop=0; //colocar valores por defeito for (i=0; i<255; i++) ifstat[ifnum].tos_list[i]=0; ifnum++; if_freenameindex(iflist_init); //libertar memoria do if_nameindex() Página 80/113
81 // lanã amento mutex if (pthread_mutex_init(&mutex, 0)!=0) exit(-1); // lanã amento pthread - comunicaã Ã o com api *************************************************************** if (pthread_create(&pthread_api, 0, api_start_routine, 0)!=0) exit(-1); // instalaã Ã o do controlo de trafego por default for (i=1; i<ifnum; i++) default_tc(ifstat[i].name); // processador de pacotes rsvp ************************************************************* for(;;) if (receive_from(&bufferin)<=0) exit(1); pthread_mutex_lock(&mutex); ra=0; if ((bufferin.pkt.iph.ihl==6) && (bufferin.pkt.ralert.opt1==(char)148)) ra=1; if ((ra==1) && (bufferin.pkt.iph.protocol==ipproto_rsvp)) // Pacote com router alert // Pacote do tipo SResv initial if (bufferin.pkt.rhead.type==(char)200) //printf("desligar alarme5\n"); alarm(0); addr.s_addr=bufferin.pkt.rdata.resv_af.rsvp_hop.paddr.s_addr; resp=make_reservation(&bufferin); // printf("pacote SResv initial: %d\nlabel anterior %d\n", (unsigned int) resp, (unsigned int) bufferin.pkt.rdata.resv_af.label_setup.label); printf("3:numero de reservas3: %d\n", resvnum); if(for_me(&bufferin)==1) if (resp==null) send_stat_fail(&bufferin,bufferin.pkt.rdata.resv_af.label_setup.label,1); else send_stat_ok(&bufferin,(union rsvdata *) resp); else addr.s_addr=bufferin.pkt.iph.daddr; bufferin.pkt.rdata.resv_af.label_setup.label=resp; bufferin.pkt.rdata.resv_af.rsvp_hop.paddr=get_iface(addr); addr2=get_iface(addr); bufferin.pkt.iph.saddr=addr2.s_addr; send_forward(&bufferin); next_resv_time(); //Pacote do tipo SResv refresh if (bufferin.pkt.rhead.type==(char)201) // printf("pacote SResv refresh label: %dlabel seguinte: %d\n\n", (unsigned int)bufferin.pkt.rdata.refresh.labels.label, (unsigned int) bufferin.pkt.rdata.refresh.label.label); Página 81/113
82 // printf("timetoexp refresh: %ds\n", timetoexp); if (verify_label(bufferin.pkt.rdata.refresh.labels.label, &bufferin)==1) //printf("verify label\n"); alarm(0); if (for_me(&bufferin)==1) resp=refresh_reservation(&bufferin); if (resp==null) send_stat_fail(&bufferin,(union rsvdata *) bufferin.pkt.rdata.refresh.label.label,1); else resp=refresh_reservation(&bufferin); if (resp==null) send_stat_fail(&bufferin,(union rsvdata *) bufferin.pkt.rdata.refresh.label.label,1); else addr=bufferin.pkt.rdata.refresh.labels.label->data.daddr; addr2=get_iface(addr); bufferin.pkt.iph.saddr=addr2.s_addr; bufferin.pkt.rdata.refresh.rsvp_hop.paddr=get_iface(addr); bufferin.pkt.rdata.refresh.labels.label=bufferin.pkt.rdata.refresh.labels.label- >data.b_label; bufferin.pkt.rdata.refresh.label.label=bufferin.pkt.rdata.refresh.labels.label- >data.label; send_forward(&bufferin); //printf("next_exp_time.label:%d \n", (unsigned int) next_exp_time.label); //printf("no_next_exp: %d\n", no_next_exp); //printf("time_to_exp: %d\n", timetoexp); next_resv_time(); else send_stat_fail(&bufferin,(union rsvdata *) bufferin.pkt.rdata.refresh.label.label,2); if ((ra==0) && (bufferin.pkth.iph.protocol==ipproto_rsvp)) // Pacote sem router alert if (bufferin.pkth.rhead.type==(char)202) // printf("pacote SResv status: %d\nlabel anterior %d\n", (unsigned int) bufferin.pkth.rdata.stat.labels.label, (unsigned int) bufferin.pkth.rdata.stat.label.label); if (verify_label(bufferin.pkth.rdata.stat.labels.label, &bufferin)) if (bufferin.pkth.rdata.stat.error_spec.error_code==0) resp=confirm_reservation(&bufferin, bufferin.pkth.rdata.stat.labels.label); if(!for_me(&bufferin)) if (resp==null) send_stat_fail(&bufferin,bufferin.pkth.rdata.stat.label.label,1); else send_stat_ok(&bufferin,(union rsvdata *) resp); Página 82/113
83 //acrescentar if para stat fail=1 if (bufferin.pkth.rdata.stat.error_spec.error_code==2) union rsvdata *tmp; alarm(0); remove_resv_time(bufferin.pkth.rdata.stat.labels.label); remove_resv(bufferin.pkth.rdata.stat.labels.label); if (!for_me(&bufferin)) addr=bufferin.pkth.rdata.stat.labels.label->data.paddr; addr2=get_iface(addr); bufferin.pkth.iph.saddr=addr2.s_addr; bufferin.pkth.iph.daddr=bufferin.pkth.rdata.stat.labels.label->data.paddr.s_addr; bufferin.pkth.rdata.stat.rsvp_hop.paddr=addr2; tmp=bufferin.pkth.rdata.stat.labels.label; bufferin.pkth.rdata.stat.labels.label=bufferin.pkth.rdata.stat.labels.label- >data.f_label; bufferin.pkth.rdata.stat.label.label=tmp->data.label; send_forward(&bufferin); next_resv_time(); if (bufferin.pkth.rhead.type==(char)203) // printf("pacote SResv tear: %d\n", (unsigned int) bufferin.pkth.rdata.tear.label.label); if (verify_label(bufferin.pkth.rdata.tear.label.label, &bufferin)==1) // printf("verify_label ok\n"); alarm(0); if (!for_me(&bufferin)) // printf("not for me\n"); addr.s_addr=bufferin.pkth.iph.daddr; addr2=get_iface(addr); bufferin.pkth.iph.saddr=addr2.s_addr; bufferin.pkth.iph.daddr=bufferin.pkth.rdata.tear.label.label->data.naddr.s_addr; bufferin.pkth.rdata.tear.label.label=bufferin.pkth.rdata.tear.label.label->data.b_label; send_forward(&bufferin); resp=tear_reservation(&bufferin); next_resv_time(); else send_stat_fail(&bufferin,(union rsvdata *) bufferin.pkth.rdata.tear.label.label,2); pthread_mutex_unlock(&mutex); // printf("fim processamento de pacotes\n"); // end - processador de pacotes rsvp******************************************************** exit(0); ; struct in_addr get_iface(struct in_addr addr) char line[512]; FILE *rfd; struct hostent *remote_host; unsigned int remote_ip; struct my_ifreq my_req; remote_host=gethostbyname(inet_ntoa(addr)); memcpy((char *) &remote_ip, remote_host->h_addr_list[0], sizeof(remote_host->h_addr_list[0])); Página 83/113
84 rfd=fopen("/proc/net/route","r"); fgets(line, sizeof(line), rfd); while(!feof(rfd)) char iface[8]; unsigned int dest, gateway, mask; unsigned int i; int aoffset; char *fields[10]; fgets(line, sizeof(line), rfd); aoffset=0; for(i=0; i<sizeof(line); i++) char *boffset; fields[aoffset++]=line+i; boffset=strchr(line+i, '\t'); if (boffset==null) i=sizeof(line); else *boffset='\0'; i=boffset-line; sscanf(fields[0],"%s", iface); sscanf(fields[1],"%x", &dest); sscanf(fields[2],"%x", &gateway); sscanf(fields[7],"%x", &mask); if (((remote_ip & mask) ^ dest) == 0) int tmpsock; strncpy(my_req.my_name, iface, sizeof(my_req.my_name)); tmpsock=socket(pf_inet, SOCK_DGRAM, IPPROTO_IP); ioctl(tmpsock, SIOCGIFADDR, &my_req); close(tmpsock); fclose(rfd); return((struct in_addr ) my_req.my_ifru.my_addr.sin_addr); return (addr); ; //recebe pacotes rsvp //retorna o tamanho do pacote e em caso de erro retorna -1 int receive_from (union ubuffer *buff) struct sockaddr_in sin; unsigned int recvb, size, sinlen; bzero(buff->data, sizeof(buff->data)); bzero((char *) &sin, sizeof(sin)); sinlen=sizeof(sin); recvb=recvfrom(rsock, buff->data, sizeof(buff->data), 0, (struct sockaddr *)&sin, &sinlen); size=ntohs(buff->pkt.iph.tot_len); if (recvb!= size) return(-1); return(recvb); ; // Faz o forward de todos os pacotes que nao interessam a este protocolo // Retorna o tamanho do pacote em caso de sucesso e -1 em caso de erro int send_forward (union ubuffer *buffer) int sock; Página 84/113
85 struct sockaddr_in sin; unsigned int sinlen; if((sock = socket(af_inet, SOCK_RAW, IPPROTO_RAW)) < 0) return(-1); bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(0); sin.sin_addr.s_addr = buffer->pkt.iph.daddr; sinlen = sizeof(sin); if(sendto(sock, &buffer->data, sizeof(buffer->data), 0, (struct sockaddr *)&sin, sinlen)!= sizeof(buffer->data)) return(-1); close(sock); return(sizeof(buffer)); ; //cria reserva em memoria, se este router for o de destino confirma a reserva. //retorna o label da reserva, em caso de erro retorna NULL union rsvdata* make_reservation(union ubuffer *buffer) union rsvdata* mresv; mresv=insert_resv(buffer); if (mresv==null) return (NULL); if (for_me(buffer)) if(confirm_reservation(buffer, mresv)==null) return (NULL); //inserir tempo de expiraã à o no fifo insert_resv_time(mresv->data.rex, mresv, 0); //instalar traffic control //obter id do interface de saida //alterar parametros no ifstat //fazer as alteraã ões necessarias no tc return(mresv); ; union rsvdata* refresh_reservation(union ubuffer *buffer) union rsvdata *resv; resv=buffer->pkt.rdata.refresh.labels.label; remove_resv_time(resv); insert_resv_time(resv->data.rex, resv, 0); return (resv); ; union rsvdata* tear_reservation(union ubuffer *buffer) remove_resv_time(buffer->pkth.rdata.tear.label.label); remove_resv(buffer->pkth.rdata.tear.label.label); return(buffer->pkth.rdata.tear.label.label); ; // Confirma as reservas em memoria // Retorna o valor do label da reserva union rsvdata* confirm_reservation(union ubuffer *buffer, union rsvdata *label) if (buffer->pkth.rhead.type==(char)202) Página 85/113
86 label->data.b_label=buffer->pkth.rdata.stat.label.label; label->data.naddr.s_addr=buffer->pkth.iph.saddr; if (label->data.resv_type==-1) label->data.resv_type=1; if (label->data.resv_type==-2) label->data.resv_type=2; return(label); if (buffer->pkt.rhead.type==(char)200) label->data.f_label=buffer->pkt.rdata.resv_gs.label_setup.label; label->data.paddr.s_addr=buffer->pkt.iph.saddr; label->data.naddr.s_addr=0; if (label->data.resv_type==-1) label->data.resv_type=1; if (label->data.resv_type==(char)-2) label->data.resv_type=(char)2; return(label); return(null); ; //Envia o stat de erro (hop by hop) //retorna o tamanho do pacote, em caso de erro retorna -1 //error - erro detectado, se error=0 faz forward do erro int send_stat_fail(union ubuffer *buffer, union rsvdata *label, int error) union ubuffer packet; int ssock, on, asinlen; struct sockaddr_in asin; int retval; struct in_addr addr; addr.s_addr=buffer->pkt.iph.saddr; //criar pacote SResvStat memset(&packet,0, sizeof(packet)); packet.pkth.iph.ihl=5; packet.pkth.iph.version=4; packet.pkth.iph.tos=tos_sig; packet.pkth.iph.protocol=ipproto_rsvp; packet.pkth.iph.daddr=addr.s_addr; //label->data.paddr.s_addr; packet.pkth.iph.ttl=50; packet.pkth.rhead.version=1; packet.pkth.rhead.type=202; packet.pkth.rhead.checksum=0; // deve ter de ser calculado packet.pkth.rhead.ttl=50; packet.pkth.rhead.length=htons(52); packet.pkth.rdata.stat.labels.datah.length=htons(8); packet.pkth.rdata.stat.labels.datah.classe=242; packet.pkth.rdata.stat.labels.datah.type=1; packet.pkth.rdata.stat.labels.label=label; packet.pkth.rdata.stat.label.datah.length=htons(8); packet.pkth.rdata.stat.label.datah.classe=243; packet.pkth.rdata.stat.label.datah.type=1; packet.pkth.rdata.stat.label.label=label; packet.pkth.rdata.stat.rsvp_hop.datah.length=htons(8); packet.pkth.rdata.stat.rsvp_hop.datah.classe=244; packet.pkth.rdata.stat.rsvp_hop.datah.type=1; packet.pkth.rdata.stat.rsvp_hop.paddr=get_iface(addr); packet.pkth.rdata.stat.sresv_parms.datah.length=htons(8); packet.pkth.rdata.stat.sresv_parms.datah.classe=245; packet.pkth.rdata.stat.sresv_parms.datah.type=1; packet.pkth.rdata.stat.sresv_parms.msgid=0;//label->data.msgid; if (buffer->pkt.rhead.type==(char)200) packet.pkth.rdata.stat.sresv_parms.rex=buffer->pkt.rdata.resv_gs.sresv_parms.rex; if (buffer->pkt.rhead.type==(char)201) packet.pkth.rdata.stat.sresv_parms.rex=buffer->pkt.rdata.refresh.sresv_parms.rex; if (buffer->pkth.rhead.type==(char)202) packet.pkth.rdata.stat.sresv_parms.rex=buffer->pkth.rdata.stat.sresv_parms.rex; Página 86/113
87 if (buffer->pkth.rhead.type==(char)203) packet.pkth.rdata.stat.sresv_parms.rex=buffer->pkth.rdata.tear.label.label->data.rex; packet.pkth.rdata.stat.sresv_parms.f=1; packet.pkth.rdata.stat.error_spec.datah.length=htons(12); packet.pkth.rdata.stat.error_spec.datah.classe=248; packet.pkth.rdata.stat.error_spec.datah.type=1; if (error!=0) addr.s_addr=buffer->pkt.iph.saddr; packet.pkth.rdata.stat.error_spec.saddr=get_iface(addr); packet.pkth.rdata.stat.error_spec.flags=0x01; packet.pkth.rdata.stat.error_spec.error_code=error; packet.pkth.rdata.stat.error_spec.error_value=0; //criar socket e enviar pacote if((ssock = socket(af_inet, SOCK_RAW, IPPROTO_RAW)) < 0) return(-1); bzero(&asin, sizeof(asin)); asin.sin_family = AF_INET; asin.sin_port = htons(0); asin.sin_addr.s_addr = addr.s_addr; asinlen = sizeof(asin); on=1; if((setsockopt(ssock, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof(on))) < 0) close(ssock); return(-1); retval=sendto(ssock, &packet, 72, 0, (struct sockaddr *)&asin, asinlen); if(retval!= 72) close(ssock); return(-1); close(ssock); return(retval); ; // envia stat_ok para o router anterior (paddr) // em caso de sucesso retorna 0 em caso de erro retorna -1 int send_stat_ok(union ubuffer *buffer, union rsvdata *label) union ubuffer packet; int ssock, on, asinlen; struct sockaddr_in asin; int retval; struct in_addr addr; addr.s_addr=buffer->pkt.iph.daddr; //criar pacote SResvStat memset(&packet,0, sizeof(packet)); packet.pkth.iph.ihl=5; packet.pkth.iph.version=4; packet.pkth.iph.tos=tos_sig; packet.pkth.iph.protocol=ipproto_rsvp; packet.pkth.iph.daddr=label->data.paddr.s_addr; packet.pkth.iph.ttl=50; packet.pkth.rhead.version=1; packet.pkth.rhead.type=202; packet.pkth.rhead.checksum=0; // deve ter de ser calculado packet.pkth.rhead.ttl=50; packet.pkth.rhead.length=htons(52); packet.pkth.rdata.stat.labels.datah.length=htons(8); packet.pkth.rdata.stat.labels.datah.classe=242; packet.pkth.rdata.stat.labels.datah.type=1; Página 87/113
88 packet.pkth.rdata.stat.labels.label=label->data.f_label; packet.pkth.rdata.stat.label.datah.length=htons(8); packet.pkth.rdata.stat.label.datah.classe=243; packet.pkth.rdata.stat.label.datah.type=1; packet.pkth.rdata.stat.label.label=label; packet.pkth.rdata.stat.rsvp_hop.datah.length=htons(8); packet.pkth.rdata.stat.rsvp_hop.datah.classe=244; packet.pkth.rdata.stat.rsvp_hop.datah.type=1; packet.pkth.rdata.stat.rsvp_hop.paddr=get_iface(addr); packet.pkth.rdata.stat.sresv_parms.datah.length=htons(8); packet.pkth.rdata.stat.sresv_parms.datah.classe=245; packet.pkth.rdata.stat.sresv_parms.datah.type=1; packet.pkth.rdata.stat.sresv_parms.msgid=label->data.msgid; if (buffer->pkt.rhead.type==(char)200) packet.pkth.rdata.stat.sresv_parms.rex=buffer->pkt.rdata.resv_gs.sresv_parms.rex; if (buffer->pkt.rhead.type==(char)201) packet.pkth.rdata.stat.sresv_parms.rex=buffer->pkt.rdata.refresh.sresv_parms.rex; if (buffer->pkth.rhead.type==(char)202) packet.pkth.rdata.stat.sresv_parms.rex=buffer->pkth.rdata.stat.sresv_parms.rex; if (buffer->pkth.rhead.type==(char)203) packet.pkth.rdata.stat.sresv_parms.rex=buffer->pkth.rdata.tear.label.label->data.rex; packet.pkth.rdata.stat.sresv_parms.f=1; packet.pkth.rdata.stat.error_spec.datah.length=htons(12); packet.pkth.rdata.stat.error_spec.datah.classe=248; packet.pkth.rdata.stat.error_spec.datah.type=1; packet.pkth.rdata.stat.error_spec.saddr.s_addr=buffer->pkt.iph.daddr; packet.pkth.rdata.stat.error_spec.flags=0x01; packet.pkth.rdata.stat.error_spec.error_code=0; packet.pkth.rdata.stat.error_spec.error_value=0; //criar socket e enviar pacote if((ssock = socket(af_inet, SOCK_RAW, IPPROTO_RAW)) < 0) return(-1); bzero(&asin, sizeof(asin)); asin.sin_family = AF_INET; asin.sin_port = htons(0); asin.sin_addr.s_addr = label->data.paddr.s_addr; asinlen = sizeof(asin); on=1; if((setsockopt(ssock, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof(on))) < 0) close(ssock); return(-1); retval=sendto(ssock, &packet, 72, 0, (struct sockaddr *)&asin, asinlen); if(retval!= 72) close(ssock); return(-1); close(ssock); return(retval); ; // cria a reserva temporaria em memoria (numa lista biligada) // retorna o label, em caso de erro retorna NULL, a reserva feita passa a ser a cabeã a da lista (resvinit) union rsvdata* insert_resv(union ubuffer* buffer) union rsvdata *resv; int pos, pos_mod; char mask=1; int i; int num_var; resv=(union rsvdata*)memalign(alignment, sizeof(union rsvdata)); Página 88/113
89 if (resv==null) return(null); if ((map_start==null) && (map_end==null)) map_start=resv; map_end=(union rsvdata*)((unsigned int) resv+(128*7)); if (map_end<resv) map_end=map_start+alignment*7+(resv-map_start)/alignment/8*alignment*8; if (map_start>resv) map_start=map_end-alignment*7-(map_end-resv)/alignment/8*alignment*8; num_var=(((unsigned int) map_end - (unsigned int) map_start)/alignment/8); pos=(((unsigned int) resv - (unsigned int) map_start)/alignment/8); pos_mod=(((unsigned int) resv - (unsigned int) map_start)/alignment%8); if (bitmap==null) bitmap=(char *)malloc(1); memset(bitmap, 0, 1); else if (num_var>num_map_var) bitmap=(char *)realloc(bitmap, num_var); // colocar se necessario os bits das novas posicoes de memoria a zero if (num_var>num_map_var) for (i=num_map_var+1; i<=num_map_var+(num_var-num_map_var); i++) bitmap[i]=(char)0; num_map_var=num_var; // activar bit correspondente mask=mask<<pos_mod; bitmap[pos]=bitmap[pos] mask; // printf("bitmap: %d\n", (unsigned char) bitmap[pos]); if (resvnum>=1) resv->data.label=(union rsvdata *)resv; resv->data.next_resv=(union rsvdata *)resvinit; resv->data.prev_resv=(union rsvdata *)resvinit->data.prev_resv; resvinit->data.prev_resv->data.next_resv=resv; resvinit->data.prev_resv=resv; resvinit=resv; if (buffer->pkt.rdata.resv_gs.flowspec.datah.classe==(unsigned char)246) resv->data.resv_type=-1; resv->data.f_label=buffer->pkt.rdata.resv_gs.label_setup.label; resv->data.b_label=0; resv->data.tos=buffer->pkt.rdata.resv_gs.sresv_parms.tos; resv->data.port=buffer->pkt.rdata.resv_gs.filter_spec.port; resv->data.msgid=1; resv->data.rex=buffer->pkt.rdata.resv_gs.sresv_parms.rex; resv->data.saddr=buffer->pkt.rdata.resv_gs.filter_spec.saddr; resv->data.daddr=buffer->pkt.rdata.resv_gs.session.daddr; resv->data.paddr=buffer->pkt.rdata.resv_gs.rsvp_hop.paddr; resv->data.ropt1=buffer->pkt.rdata.resv_gs.flowspec.tbrate; resv->data.ropt2=(long)buffer->pkt.rdata.resv_gs.flowspec.tbsize; resv->data.ropt3=0; if (buffer->pkt.rdata.resv_af.flowspec.datah.classe==(unsigned char)247) Página 89/113
90 resv->data.resv_type=-2; resv->data.f_label=(union rsvdata *)buffer->pkt.rdata.resv_af.label_setup.label; resv->data.b_label=0; resv->data.tos=buffer->pkt.rdata.resv_af.sresv_parms.tos; resv->data.port=buffer->pkt.rdata.resv_af.filter_spec.port; resv->data.msgid=1; resv->data.rex=buffer->pkt.rdata.resv_af.sresv_parms.rex; resv->data.saddr=buffer->pkt.rdata.resv_af.filter_spec.saddr; resv->data.daddr=buffer->pkt.rdata.resv_af.session.daddr; resv->data.paddr=buffer->pkt.rdata.resv_af.rsvp_hop.paddr; resv->data.ropt1=(long)buffer->pkt.rdata.resv_af.flowspec.dgrate1; resv->data.ropt2=(long)buffer->pkt.rdata.resv_af.flowspec.dgrate2; resv->data.ropt3=(long)buffer->pkt.rdata.resv_af.flowspec.droprate; resvnum++; if (resvnum==0) resvinit=resv; resv->data.label=(union rsvdata *)resv; resv->data.next_resv=(union rsvdata *)resv; resv->data.prev_resv=(union rsvdata *)resv; if (buffer->pkt.rdata.resv_gs.flowspec.datah.classe==(unsigned char)246) resv->data.resv_type=-1; resv->data.f_label=(union rsvdata *)buffer->pkt.rdata.resv_gs.label_setup.label; resv->data.b_label=0; resv->data.tos=buffer->pkt.rdata.resv_gs.sresv_parms.tos; resv->data.port=buffer->pkt.rdata.resv_gs.filter_spec.port; resv->data.msgid=1; resv->data.rex=buffer->pkt.rdata.resv_gs.sresv_parms.rex; resv->data.saddr=buffer->pkt.rdata.resv_gs.filter_spec.saddr; resv->data.daddr=buffer->pkt.rdata.resv_gs.session.daddr; resv->data.paddr=buffer->pkt.rdata.resv_gs.rsvp_hop.paddr; resv->data.ropt1=buffer->pkt.rdata.resv_gs.flowspec.tbrate; resv->data.ropt2=(long)buffer->pkt.rdata.resv_gs.flowspec.tbsize; resv->data.ropt3=0; if (buffer->pkt.rdata.resv_af.flowspec.datah.classe==(unsigned char)247) resv->data.resv_type=-2; resv->data.f_label=(union rsvdata *)buffer->pkt.rdata.resv_af.label_setup.label; resv->data.b_label=0; resv->data.tos=buffer->pkt.rdata.resv_af.sresv_parms.tos; resv->data.port=buffer->pkt.rdata.resv_af.filter_spec.port; resv->data.msgid=1; resv->data.rex=buffer->pkt.rdata.resv_af.sresv_parms.rex; resv->data.saddr=buffer->pkt.rdata.resv_af.filter_spec.saddr; resv->data.daddr=buffer->pkt.rdata.resv_af.session.daddr; resv->data.paddr=buffer->pkt.rdata.resv_af.rsvp_hop.paddr; resv->data.ropt1=(long)buffer->pkt.rdata.resv_af.flowspec.dgrate1; resv->data.ropt2=(long)buffer->pkt.rdata.resv_af.flowspec.dgrate2; resv->data.ropt3=(long)buffer->pkt.rdata.resv_af.flowspec.droprate; resvnum++; setitimer(itimer_real, &time_old, NULL); return(resv); ; int remove_resv(union rsvdata* rdata) int pos, pos_mod; char mask=1; // printf("remove resv start: %d\n", (unsigned int) rdata); //colocar bit do mapa a zero pos=(((unsigned int) rdata - (unsigned int) map_start)/alignment/8); Página 90/113
91 pos_mod=(((unsigned int) rdata - (unsigned int) map_start)/alignment%8); mask=mask<<pos_mod; bitmap[pos]=bitmap[pos]&(~mask); // printf("bitmap remove: %d\n", (unsigned char) bitmap[pos]); if (resvnum==1) if (rdata!=null) free(rdata); resvnum=0; if (resvnum>1) rdata->data.prev_resv->data.next_resv=rdata->data.next_resv; rdata->data.next_resv->data.prev_resv=rdata->data.prev_resv; if (rdata!=null) free(rdata); resvnum--; if (resvnum==0) printf("no reservations\n"); printf("1:numero de reservas1: %d - end\n",resvnum); return(0); ; //verifica se o endereã o de destino do pacote pertence a esta mã quina //retorna 1 se for verdade, 0 se nao for verdade (tipo BOOLEAN) int for_me(union ubuffer *buffer) int i; int ret; struct in_addr addr; union rsvdata *rsv; ret=0; if (buffer->pkt.rhead.type==(char)200) addr.s_addr=buffer->pkt.rdata.resv_gs.session.daddr.s_addr; if (buffer->pkt.rhead.type==(char)201) addr.s_addr=buffer->pkt.rdata.refresh.labels.label->data.daddr.s_addr; if (buffer->pkth.rhead.type==(char)202) rsv=buffer->pkth.rdata.stat.labels.label; addr=rsv->data.saddr; if (buffer->pkth.rhead.type==(char)203) addr.s_addr=buffer->pkth.rdata.tear.label.label->data.daddr.s_addr; for(i=0; i<ifnum && ret==0; i++) if(addr.s_addr==ifnames[i].addr.s_addr) ret=1; return(ret); ; //Modulo de comunicaã Ã o com o API //Caso type=0 apaga reserva, type=1 cria reserva GS, type=2 cria reserva AF //Retorna -1 em caso de erro, zero em caso de sucesso int com_api () Página 91/113
92 int usock; struct sockaddr_un servaddr; struct sockaddr_un from; socklen_t fromlen; int retval; union ucomapi api_data; // printf("api START\n"); unlink(unixstr_path); if ((usock=socket(pf_unix, SOCK_DGRAM, 0)) < 0) return(-1); bzero (&api_data.buffer, sizeof(api_data)); bzero (&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_UNIX; strcpy(servaddr.sun_path, UNIXSTR_PATH); if (bind(usock, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) close(usock); return(-1); fromlen=sizeof(from); if(recvfrom(usock, api_data.buffer, sizeof(api_data), 0,(struct sockaddr *) &from, &fromlen)==-1) close(usock); return(-1); pthread_mutex_lock(&mutex); retval=api_data.comapi.type; //Apagar reserva if (api_data.comapi.type==0) if(api_tear_reservation(&api_data)==-1) retval=-1; //Fazer reserva GS if (api_data.comapi.type==1) if(api_gs_reservation(&api_data)==-1) retval=-1; //Fazer reserva AF if (api_data.comapi.type==2) if(api_af_reservation(&api_data)==-1) retval=-1; pthread_mutex_unlock(&mutex); if (api_data.comapi.type!=0 && api_data.comapi.type!=1 && api_data.comapi.type!=2) retval=-1; if (retval!=-1) retval=0; api_data.comapi.type=retval; // printf("api:label=%d\n",api_data.comapi.label); // retornar ao API o resultado da operaã Ã o if(sendto(usock, api_data.buffer, sizeof(api_data), 0,(struct sockaddr *) &from, sizeof(from))<0) close(usock); return(-1); close (usock); Página 92/113
93 next_resv_time(); // printf("api END\n"); return(retval); ; int api_tear_reservation (union ucomapi *api_data) union ubuffer packet; int asock, on, asinlen; struct sockaddr_in asin; union rsvdata *label; label=(union rsvdata*)api_data->comapi.label; if(verify_label(label, NULL)==1) //enviar pacote tear memset(&packet,0, sizeof(packet)); packet.pkth.iph.ihl=5; packet.pkth.iph.version=4; packet.pkth.iph.tos=label->data.tos; packet.pkth.iph.protocol=ipproto_rsvp; packet.pkth.iph.daddr=label->data.naddr.s_addr; packet.pkth.iph.ttl=50; packet.pkth.rhead.version=1; packet.pkth.rhead.type=203; packet.pkth.rhead.checksum=0; // deve ter de ser calculado packet.pkth.rhead.ttl=50; packet.pkth.rhead.length=htons(24); //tem de ser calculado packet.pkth.rdata.tear.label.datah.length=htons(8); packet.pkth.rdata.tear.label.datah.classe=242; packet.pkth.rdata.tear.label.datah.type=1; packet.pkth.rdata.tear.label.label=label->data.b_label; packet.pkth.rdata.tear.rsvp_hop.datah.length=htons(8); packet.pkth.rdata.tear.rsvp_hop.datah.classe=244; packet.pkth.rdata.tear.rsvp_hop.datah.type=1; packet.pkth.rdata.tear.rsvp_hop.paddr=get_iface(label->data.naddr); //criar socket e enviar pacote if((asock = socket(af_inet, SOCK_RAW, IPPROTO_RAW)) < 0) return(-1); bzero(&asin, sizeof(asin)); asin.sin_family = AF_INET; asin.sin_port = htons(0); asin.sin_addr.s_addr = label->data.naddr.s_addr; asinlen = sizeof(asin); on=1; if((setsockopt(asock, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof(on))) < 0) close(asock); return(-1); if(sendto(asock, &packet.data, 44, 0, (struct sockaddr *)&asin, asinlen)!= 44) close(asock); return(-1); remove_resv_time(label); remove_resv(label); close(asock); return (0); return(-1); ; Página 93/113
94 int api_gs_reservation (union ucomapi *api_data) union ubuffer packet; int asock, on, asinlen; struct sockaddr_in asin; union rsvdata *label; // se o endereã o de destino pertencer a esta maquina, negar pedido // por razoes de teste ainda nao foi implementado //criar reserva temporaria em memoria label=(union rsvdata *)make_localresv(api_data); if(label==null) return(-1); api_data->comapi.label=(unsigned int)label; //criar pacote SResv initial memset(&packet,0, sizeof(packet)); packet.pkt.iph.ihl=6; packet.pkt.iph.version=4; packet.pkt.iph.tos=api_data->comapi.tos; packet.pkt.iph.protocol=ipproto_rsvp; packet.pkt.iph.daddr=api_data->comapi.daddr.s_addr; packet.pkt.iph.ttl=50; packet.pkt.ralert.opt1=(char)148; packet.pkt.ralert.opt2=(char)4; packet.pkt.ralert.opt3=(char)0; packet.pkt.ralert.opt4=(char)0; packet.pkt.rhead.version=1; packet.pkt.rhead.type=200; packet.pkt.rhead.checksum=0; // deve ter de ser calculado packet.pkt.rhead.ttl=50; packet.pkt.rhead.length=htons(17*4); //tem de ser calculado packet.pkt.rdata.resv_gs.session.datah.length=htons(12); packet.pkt.rdata.resv_gs.session.datah.classe=240; packet.pkt.rdata.resv_gs.session.datah.type=1; packet.pkt.rdata.resv_gs.session.daddr.s_addr=api_data->comapi.daddr.s_addr; packet.pkt.rdata.resv_gs.session.protoid=ipproto_udp; //protocolo ip em uso pelo fluxo packet.pkt.rdata.resv_gs.session.vport=api_data->comapi.port; packet.pkt.rdata.resv_gs.filter_spec.datah.length=htons(12); packet.pkt.rdata.resv_gs.filter_spec.datah.classe=241; packet.pkt.rdata.resv_gs.filter_spec.datah.type=1; packet.pkt.rdata.resv_gs.filter_spec.saddr=get_iface(api_data->comapi.daddr); //Endereà o de origem packet.pkt.rdata.resv_gs.filter_spec.port=api_data->comapi.port; packet.pkt.rdata.resv_gs.label_setup.datah.length=htons(8); packet.pkt.rdata.resv_gs.label_setup.datah.classe=242; packet.pkt.rdata.resv_gs.label_setup.datah.type=1; packet.pkt.rdata.resv_gs.label_setup.label=(union rsvdata *)label; //valor label setup packet.pkt.rdata.resv_gs.rsvp_hop.datah.length=htons(8); packet.pkt.rdata.resv_gs.rsvp_hop.datah.classe=244; packet.pkt.rdata.resv_gs.rsvp_hop.datah.type=1; packet.pkt.rdata.resv_gs.rsvp_hop.paddr=get_iface(api_data->comapi.daddr); packet.pkt.rdata.resv_gs.sresv_parms.datah.length=htons(8); packet.pkt.rdata.resv_gs.sresv_parms.datah.classe=245; packet.pkt.rdata.resv_gs.sresv_parms.datah.type=1; packet.pkt.rdata.resv_gs.sresv_parms.msgid=1; //numero sequencial packet.pkt.rdata.resv_gs.sresv_parms.rex=api_data->comapi.rex; //valor do tempo de reserva 2^rex segundos packet.pkt.rdata.resv_gs.sresv_parms.tos=api_data->comapi.tos; //segundo o rfc 3140 packet.pkt.rdata.resv_gs.sresv_parms.f=1; //segundo o rfc 3140 packet.pkt.rdata.resv_gs.flowspec.datah.length=htons(12); packet.pkt.rdata.resv_gs.flowspec.datah.classe=246; packet.pkt.rdata.resv_gs.flowspec.datah.type=1; packet.pkt.rdata.resv_gs.flowspec.tbrate=api_data->comapi.opt1; packet.pkt.rdata.resv_gs.flowspec.tbsize=(long)api_data->comapi.opt2; //criar socket e enviar pacote if((asock = socket(af_inet, SOCK_RAW, IPPROTO_RAW)) < 0) return(-1); Página 94/113
95 bzero(&asin, sizeof(asin)); asin.sin_family = AF_INET; asin.sin_port = htons(0); asin.sin_addr.s_addr = api_data->comapi.daddr.s_addr; asinlen = sizeof(asin); on=1; if((setsockopt(asock, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof(on))) < 0) close(asock); return(-1); if(sendto(asock, &packet.data, 92, 0, (struct sockaddr *)&asin, asinlen)!= 92) close(asock); return(-1); close(asock); return(0); ; int api_af_reservation (union ucomapi *api_data) union ubuffer packet; int asock, on, asinlen; struct sockaddr_in asin; union rsvdata *label; //criar reserva temporaria em memoria label=(union rsvdata *)make_localresv(api_data); if(label==null) return(-1); api_data->comapi.label=(unsigned int)label; //criar pacote SResv initial memset(&packet,0, sizeof(packet)); packet.pkt.iph.ihl=6; packet.pkt.iph.version=4; packet.pkt.iph.tos=api_data->comapi.tos; packet.pkt.iph.protocol=ipproto_rsvp; packet.pkt.iph.daddr=api_data->comapi.daddr.s_addr; packet.pkt.iph.ttl=50; packet.pkt.ralert.opt1=(char)148; packet.pkt.ralert.opt2=(char)4; packet.pkt.ralert.opt3=(char)0; packet.pkt.ralert.opt4=(char)0; packet.pkt.rhead.version=1; packet.pkt.rhead.type=200; packet.pkt.rhead.checksum=0; // deve ter de ser calculado packet.pkt.rhead.ttl=50; packet.pkt.rhead.length=htons(18*4); //tem de ser calculado packet.pkt.rdata.resv_af.session.datah.length=htons(12); packet.pkt.rdata.resv_af.session.datah.classe=240; packet.pkt.rdata.resv_af.session.datah.type=1; packet.pkt.rdata.resv_af.session.daddr.s_addr=api_data->comapi.daddr.s_addr; packet.pkt.rdata.resv_af.session.protoid=ipproto_udp; //protocolo ip em uso pelo fluxo packet.pkt.rdata.resv_af.session.vport=api_data->comapi.port; packet.pkt.rdata.resv_af.filter_spec.datah.length=htons(12); packet.pkt.rdata.resv_af.filter_spec.datah.classe=241; packet.pkt.rdata.resv_af.filter_spec.datah.type=1; packet.pkt.rdata.resv_af.filter_spec.saddr=get_iface(api_data->comapi.daddr); //Endereà o de origem packet.pkt.rdata.resv_af.filter_spec.port=api_data->comapi.port; packet.pkt.rdata.resv_af.label_setup.datah.length=htons(8); packet.pkt.rdata.resv_af.label_setup.datah.classe=242; packet.pkt.rdata.resv_af.label_setup.datah.type=1; packet.pkt.rdata.resv_af.label_setup.label=(union rsvdata *)label; //valor label setup packet.pkt.rdata.resv_af.rsvp_hop.datah.length=htons(8); packet.pkt.rdata.resv_af.rsvp_hop.datah.classe=244; Página 95/113
96 packet.pkt.rdata.resv_af.rsvp_hop.datah.type=1; packet.pkt.rdata.resv_af.rsvp_hop.paddr=get_iface(api_data->comapi.daddr); packet.pkt.rdata.resv_af.sresv_parms.datah.length=htons(8); packet.pkt.rdata.resv_af.sresv_parms.datah.classe=245; packet.pkt.rdata.resv_af.sresv_parms.datah.type=1; packet.pkt.rdata.resv_af.sresv_parms.msgid=1; //numero sequencial packet.pkt.rdata.resv_af.sresv_parms.rex=api_data->comapi.rex; //valor do tempo de reserva 2^rex segundos packet.pkt.rdata.resv_af.sresv_parms.tos=api_data->comapi.tos; //segundo o rfc 3140 packet.pkt.rdata.resv_af.sresv_parms.f=1; //segundo o rfc 3140 packet.pkt.rdata.resv_af.flowspec.datah.length=htons(16); packet.pkt.rdata.resv_af.flowspec.datah.classe=247; packet.pkt.rdata.resv_af.flowspec.datah.type=1; packet.pkt.rdata.resv_af.flowspec.dgrate1=api_data->comapi.opt1; packet.pkt.rdata.resv_af.flowspec.dgrate2=(long)api_data->comapi.opt2; packet.pkt.rdata.resv_af.flowspec.droprate=(long)api_data->comapi.opt3; //criar socket e enviar pacote if((asock = socket(af_inet, SOCK_RAW, IPPROTO_RAW)) < 0) return(-1); bzero(&asin, sizeof(asin)); asin.sin_family = AF_INET; asin.sin_port = htons(0); asin.sin_addr.s_addr = api_data->comapi.daddr.s_addr; asinlen = sizeof(asin); on=1; if((setsockopt(asock, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof(on))) < 0) close(asock); return(-1); if(sendto(asock, &packet.data, 92, 0, (struct sockaddr *)&asin, asinlen)!= 92) close(asock); return(-1); close(asock); return(0); ; // Cria reservas vindas a pedido do api // retorna o endereã o da reserva, em caso de erro retorna NULL union rsvdata* make_localresv(union ucomapi *api_data) union rsvdata *resv; int num_var; int pos, pos_mod; char mask=1; int i; resv=(union rsvdata*)memalign(alignment, sizeof(union rsvdata)); if (resv==null) return(null); if ((map_start==null) && (map_end==null)) map_start=resv; map_end=(union rsvdata*)((unsigned int) resv+(128*7)); if (map_end<resv) map_end=map_start+alignment*7+(resv-map_start)/alignment/8*alignment*8; if (map_start>resv) map_start=map_end-alignment*7-(map_end-resv)/alignment/8*alignment*8; Página 96/113
97 num_var=(((unsigned int) map_end - (unsigned int) map_start)/alignment/8); pos=(((unsigned int) resv - (unsigned int) map_start)/alignment/8); pos_mod=(((unsigned int) resv - (unsigned int) map_start)/alignment%8); if (bitmap==null) bitmap=(char *)malloc(1); memset(bitmap, 0, 1); else if (num_var>num_map_var) bitmap=(char *)realloc(bitmap, num_var); // colocar se necessario os bits das novas posicoes de memoria a zero if (num_var>num_map_var) for (i=num_map_var+1; i<=num_map_var+(num_var-num_map_var); i++) bitmap[i]=(char)0; num_map_var=num_var; // activar bit correspondente mask=mask<<pos_mod; bitmap[pos]=bitmap[pos] mask; // printf("bitmap: %d\n", (unsigned char) bitmap[pos]); if (resvnum>=1) resv->data.label=(union rsvdata *)resv; resv->data.next_resv=(union rsvdata *)resvinit; resv->data.prev_resv=(union rsvdata *)resvinit->data.prev_resv; resvinit->data.prev_resv->data.next_resv=resv; resvinit->data.prev_resv=resv; resvinit=resv; if (resvnum==0) resvinit=resv; resv->data.label=(union rsvdata *)resv; resv->data.next_resv=(union rsvdata *)resv; resv->data.prev_resv=(union rsvdata *)resv; if (api_data->comapi.type==1) resv->data.resv_type=-1; if (api_data->comapi.type==2) resv->data.resv_type=-2; resv->data.b_label=0; resv->data.f_label=0; resv->data.tos=api_data->comapi.tos; resv->data.port=api_data->comapi.port; resv->data.pid=api_data->comapi.pid; resv->data.msgid=1; resv->data.rex=api_data->comapi.rex; resv->data.saddr=get_iface(api_data->comapi.daddr); resv->data.daddr=api_data->comapi.daddr; resv->data.ropt1=api_data->comapi.opt1; resv->data.ropt2=api_data->comapi.opt2; if (api_data->comapi.type==2) resv->data.ropt3=api_data->comapi.opt2; else resv->data.ropt3=0; resvnum++; printf("2:numero de reservas2: %d\n",resvnum); Página 97/113
98 if (insert_resv_time(api_data->comapi.rex-2, resv, 1)==0) return(null); return(resv); ; void *api_start_routine(void *arg) for(;;) if(com_api()==-1) exit(-1); ; //verifica se o label existe na lista de reservas //retorna 0 em caso de nao existir e 1 em caso de existir int verify_label (union rsvdata* resv, union ubuffer* buffer) int pos, pos_mod; char mask=1; if (resv==null) return(0); if((resv<map_start) (resv>map_end)) return (0); pos=(((unsigned int) resv - (unsigned int) map_start)/alignment/8); pos_mod=(((unsigned int) resv - (unsigned int) map_start)/alignment%8); mask=mask<<pos_mod; if((bitmap[pos]&mask)==mask) /* if (buffer!=null) if (buffer->pkt.rhead.type==(char)201) if(buffer->pkt.iph.saddr!=resv->data.paddr.s_addr) return(0); return(1); */ return(1); return(0); ; int send_refresh (union rsvdata *label) union ubuffer packet; int asock, on, asinlen; struct sockaddr_in asin; //criar pacote SResv refresh memset(&packet,0, sizeof(packet)); packet.pkt.iph.ihl=6; packet.pkt.iph.version=4; packet.pkt.iph.tos=label->data.tos; packet.pkt.iph.protocol=ipproto_rsvp; packet.pkt.iph.daddr=label->data.daddr.s_addr; packet.pkt.iph.ttl=50; packet.pkt.ralert.opt1=(char)148; packet.pkt.ralert.opt2=(char)4; packet.pkt.ralert.opt3=(char)0; packet.pkt.ralert.opt4=(char)0; packet.pkt.rhead.version=1; packet.pkt.rhead.type=201; Página 98/113
99 packet.pkt.rhead.checksum=0; // deve ter de ser calculado packet.pkt.rhead.ttl=50; packet.pkt.rhead.length=htons(8*4); //tem de ser calculado packet.pkt.rdata.refresh.label.datah.length=htons(8); packet.pkt.rdata.refresh.label.datah.classe=242; packet.pkt.rdata.refresh.label.datah.type=1; packet.pkt.rdata.refresh.label.label=label; packet.pkt.rdata.refresh.labels.datah.length=htons(8); packet.pkt.rdata.refresh.labels.datah.classe=242; packet.pkt.rdata.refresh.labels.datah.type=1; packet.pkt.rdata.refresh.labels.label=label->data.b_label; packet.pkt.rdata.refresh.rsvp_hop.datah.length=htons(8); packet.pkt.rdata.refresh.rsvp_hop.datah.classe=244; packet.pkt.rdata.refresh.rsvp_hop.datah.type=1; packet.pkt.rdata.refresh.rsvp_hop.paddr=get_iface(label->data.daddr); packet.pkt.rdata.refresh.sresv_parms.datah.length=htons(8); packet.pkt.rdata.refresh.sresv_parms.datah.classe=245; packet.pkt.rdata.refresh.sresv_parms.datah.type=1; packet.pkt.rdata.refresh.sresv_parms.msgid=(label->data.msgid++); //numero sequencial packet.pkt.rdata.refresh.sresv_parms.rex=label->data.rex; //valor do tempo de reserva 2^rex segundos packet.pkt.rdata.refresh.sresv_parms.tos=label->data.tos; //segundo o rfc 3140 packet.pkt.rdata.refresh.sresv_parms.f=1; //segundo o rfc 3140 //criar socket e enviar pacote if((asock = socket(af_inet, SOCK_RAW, IPPROTO_RAW)) < 0) return(-1); bzero(&asin, sizeof(asin)); asin.sin_family = AF_INET; asin.sin_port = htons(0); asin.sin_addr.s_addr = label->data.daddr.s_addr; asinlen = sizeof(asin); on=1; if((setsockopt(asock, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof(on))) < 0) close(asock); return(-1); if(label->data.b_label!=0) if(sendto(asock, &packet.data, 52, 0, (struct sockaddr *)&asin, asinlen)!= 52) close(asock); return(-1); close(asock); return(0); ; void sig_alarm(int signum) struct rsvtime sig_exp_time; int sig_timetoexp; int i; int num=0; //printf("desligar alarme3\n"); alarm(0); no_next_exp=0; timetoexp=0; sig_exp_time.end_time=0; sig_exp_time.label=0; sig_timetoexp=0; for (i=0; i<8; i++) if(resvtimenum[i]>0) Página 99/113
100 if ((sig_exp_time.end_time==0) (sig_exp_time.end_time>resvtime[i]->end_time)) sig_exp_time.label=resvtime[i]->label; sig_exp_time.end_time=resvtime[i]->end_time; sig_exp_time.local=resvtime[i]->local; sig_exp_time.rex=resvtime[i]->rex; sig_timetoexp=(unsigned int)sig_exp_time.end_time-(unsigned int)time(null); while ((sig_timetoexp<=0) && (sig_exp_time.label!=0) && (num<100)) if (sig_exp_time.local==0) //remover reserva nao local remove_resv(sig_exp_time.label); remove_resv_time(sig_exp_time.label); sig_exp_time.local=-1; if ((sig_exp_time.local==1) && (sig_exp_time.label->data.resv_type<0)) //remover reserva local remove_resv(sig_exp_time.label); remove_resv_time(sig_exp_time.label); sig_exp_time.local=-1; if ((sig_exp_time.local==1) && (sig_exp_time.label->data.resv_type>=0)) //refrescar reserva local remove_resv_time(sig_exp_time.label); insert_resv_time(sig_exp_time.rex, sig_exp_time.label, 1); send_refresh(sig_exp_time.label); sig_exp_time.end_time=0; sig_exp_time.label=0; sig_timetoexp=0; for (i=0; i<8; i++) if(resvtimenum[i]>0) if ((sig_exp_time.end_time==0) (sig_exp_time.end_time>resvtime[i]->end_time)) sig_exp_time.label=resvtime[i]->label; sig_exp_time.end_time=resvtime[i]->end_time; sig_exp_time.local=resvtime[i]->local; sig_exp_time.rex=resvtime[i]->rex; sig_timetoexp=(unsigned int)sig_exp_time.end_time-(unsigned int)time(null); num++; if (num==100) time_new.it_value.tv_sec=0; time_new.it_value.tv_usec=10000; time_new.it_interval.tv_sec=0; time_new.it_interval.tv_usec=0; setitimer(itimer_real, &time_new, NULL); no_next_exp=1; timetoexp=0; //printf("next time in: 10ms\n"); if (no_next_exp==0) Página 100/113
101 ; if (sig_exp_time.label!=0) if (sig_timetoexp>0) time_new.it_value.tv_sec=sig_timetoexp; time_new.it_value.tv_usec=0; time_new.it_interval.tv_sec=0; time_new.it_interval.tv_usec=0; setitimer(itimer_real, &time_new, NULL); //printf("next time in: %ds\n",sig_timetoexp); timetoexp=sig_timetoexp; int remove_resv_time(union rsvdata *label) struct rsvtime *resv_t; resv_t=label->data.rsv_time; if (resv_t->last!=null) resv_t->last->next=resv_t->next; else resvtime[resv_t->rex]=resv_t->next; if (resv_t->next!=null) resv_t->next->last=resv_t->last; else endresvtime[resv_t->rex]=resv_t->last; resvtimenum[resv_t->rex]--; label->data.rsv_time=0; free(resv_t); return(0); //Insere a reserva nos fifos do tempo de expiraã Ã o da reserva //retorna 1 em caso de sucesso, 0 em caso de erro //reserva local: local=1, reserva nã o local: local=0 //tem de ser executada com o mutex lock int insert_resv_time(int rex, union rsvdata *label, char local) struct rsvtime *resv_t; resv_t=(struct rsvtime*)malloc(sizeof(struct rsvtime)); if(resv_t==null) return(0); // printf("resv_t: %d\n", (unsigned int) resv_t); resv_t->end_time=time(null); resv_t->end_time+=(int)pow((double)2,(double)rex); resv_t->label=label; resv_t->local=local; resv_t->rex=rex; resv_t->next=null; if (resvtimenum[rex]==0) resv_t->last=null; resvtime[rex]=resv_t; endresvtime[rex]=resv_t; else endresvtime[rex]->next=resv_t; Página 101/113
102 resv_t->last=endresvtime[rex]; endresvtime[rex]=resv_t; resvtimenum[rex]++; label->data.rsv_time=resv_t; return(1); ; //Procura a på oxia reserva a expirar nos fifos de reservas //coloca em next_exp_resv o label da proxima reserva a expirar //retorna 0 em caso de sucesso, -1 em caso de erro //instala o signal para o temporizador se necessã rio //tem de ser executada com o mutex lock int next_resv_time() int time; getitimer(itimer_real, &time_old); if (resvnum<=0) return(0); if (resvnum>1) if ((time_old.it_value.tv_sec==0) && (time_old.it_value.tv_usec<=10) && (time_old.it_value.tv_usec!=0)) // printf("menos de 10ms\n"); return (0); //printf("desligar alarme4\n"); alarm(0); timetoexp=0; time=get_exp_time(); if (next_exp_time.label!=0) if (time>0) time_new.it_value.tv_sec=time; time_new.it_value.tv_usec=0; time_new.it_interval.tv_sec=0; time_new.it_interval.tv_usec=0; setitimer(itimer_real, &time_new, NULL); // printf("2:next time in: %ds\n",time); if ((next_exp_time.label!=0) && (time<=0)) raise(sigalrm); timetoexp=time; if ((next_exp_time.label==0) && (time<=0)) // printf("2:no next time: 1s\n"); alarm(1); timetoexp=1; return(0); ; int get_exp_time () int i; int rettime; Página 102/113
103 if (resvnum<=0) //printf("getexptime return -1\n"); return(-1); next_exp_time.end_time=0; next_exp_time.label=0; rettime=0; for (i=0; i<8; i++) if(resvtimenum[i]>0) if ((next_exp_time.end_time==0) (next_exp_time.end_time>resvtime[i]->end_time)) next_exp_time.label=resvtime[i]->label; next_exp_time.end_time=resvtime[i]->end_time; next_exp_time.local=resvtime[i]->local; next_exp_time.rex=resvtime[i]->rex; rettime=(unsigned int)next_exp_time.end_time-(unsigned int)time(null); //printf("getexptime return %d: %d\n", rettime, (unsigned int)next_exp_time.label); return (rettime); ; RSVPD.h /*************************************************************************** * Copyright (C) 2005 by / * * [email protected] / [email protected] * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA , USA. * ***************************************************************************/ // RSVP SRBQ Deamon header #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/wait.h> #include <sys/ioctl.h> #include <sys/time.h> #include <arpa/inet.h> #include <net/if.h> #include <net/route.h> #include <linux/sockios.h> #include <stdlib.h> Página 103/113
104 #include <unistd.h> #include <getopt.h> #include <stdio.h> #include <netdb.h> #include <errno.h> #include <string.h> #include <signal.h> #include <errno.h> #include <pthread.h> #include <time.h> #include <math.h> #include <malloc.h> #include "tcscript.h" #define TOS_SIG 0xc0 //tos para os pacotes de sinalizaã Ã o #define UNIXSTR_PATH "/tmp/unix.str" #define UNIXSTR_PATH2 "/tmp/unix2.str" #define _XOPEN_SOURCE 600 //para o posix_memalign #define ALIGNMENT 128 #define NUM_IFACES 10 struct if_stat char name[10]; struct in_addr addr; unsigned int stbr; unsigned int stbs; unsigned int sdrt; unsigned int sdrt2; unsigned int sdrop; unsigned int tos_list[255]; ; struct rsvtime long end_time; // fim da reserva union rsvdata *label; // label local da reserva int local; // 1- reserva local, 0- reserva nao local int rex; struct rsvtime *next; // proxima reserva no fifo struct rsvtime *last; ; //Estrutura para comunicaã Ã o com API struct scomapi int pid; // pid do programa fonte char type; // tipo de reserva: 0 - apagar, 1 - GS, 2 - AF char tos; // tos associado ao fluxo unsigned int rex; // tempo de expiraã Ã o da reserva int port; // porta para o fluxo struct in_addr daddr; // endereã o de destino long opt1; // GS: token bucket rate, AF: degradation rate 1 long opt2; // GS: token bucket size, AF: degradation rate 2 long opt3; // GS: nao usado, AF: drop rate unsigned int label; // label da reserva - para enviar tear ; union ucomapi struct scomapi comapi; char buffer[sizeof(struct scomapi)]; ; //Estrutura das reservas em memoria struct resv_data union rsvdata *label; // endereã o de memoria da reserva union rsvdata *next_resv;// proxima reserva na lista de reservas union rsvdata *prev_resv;// reserva anterior na lista de reservas union rsvdata *b_label; // endereã o da posiã Ã o de memoria no router seguinte union rsvdata *f_label; // endereã o da posiã Ã o de memoria no router anterior struct rsvtime *rsv_time;// endereã o da posiã Ã o de momoria da lista de tempos int resv_type; // -2 waiting AF, -1 waiting GS, 0 - free, 1 - GS, 2 - AF char tos; // tos associado ao fluxo int msgid; // id sequencial identificador da mensagem int rex; Página 104/113
105 int port; int pid; struct in_addr saddr; // endereã o de origem struct in_addr daddr; // endereã o de destino struct in_addr paddr; // endereã o do router anterior struct in_addr naddr; // endereã o do router seguinte long ropt1; // opã Ã o GS - tb rate, AF - degradation rate 1 long ropt2; // opã Ã o GS - tb size, AF - degradation rate 2 long ropt3; // opã Ã o GS - nao usada, AF - Drop rate ; union rsvdata struct resv_data data; char buffer[sizeof(struct resv_data)]; ; //rsvp header struct rsvphead int flags:4; int version:4; char type:8; int checksum:16; char ttl:8; char reserved:8; int length:16; ; //rsvp data header struct rsvpdatah unsigned short length; unsigned char classe; unsigned char type; ; //Session data struct struct rsession struct rsvpdatah datah; struct in_addr daddr; char protoid; char flags; int vport:16; ; //Filter_Spec data struct struct rfilter_spec struct rsvpdatah datah; struct in_addr saddr; short reserved; short port; ; //Label_Setup data struct struct rlabel_setup struct rsvpdatah datah; union rsvdata *label; ; //Label data struct struct rlabel struct rsvpdatah datah; union rsvdata *label; ; //RSVP_Hop data struct struct rrsvp_hop struct rsvpdatah datah; struct in_addr paddr; ; //SResv_Parms data Struct struct rsresv_parms struct rsvpdatah datah; Página 105/113
106 unsigned int rex:3; int r:1; int msgid:4; int flags:8; int r2:2; int tos:6; int r3:1; int f:1; int r4:6; ; //GS Flow_Spec data struct struct rgsflowspec struct rsvpdatah datah; int tbrate; float tbsize; ; //AF Flow_Spec data struct struct rafflowspec struct rsvpdatah datah; float dgrate1; float dgrate2; float droprate; ; //Error spec data struct struct rerror_spec struct rsvpdatah datah; struct in_addr saddr; char flags; char error_code; short error_value; ; //error node //GS reservation data struct data_resv_gs struct rsession session; struct rfilter_spec filter_spec; struct rlabel_setup label_setup; struct rrsvp_hop rsvp_hop; struct rsresv_parms sresv_parms; struct rgsflowspec flowspec; ; //AF reservation data struct data_resv_af struct rsession session; struct rfilter_spec filter_spec; struct rlabel_setup label_setup; struct rrsvp_hop rsvp_hop; struct rsresv_parms sresv_parms; struct rafflowspec flowspec; ; //Refresh reservation data struct data_refresh struct rlabel label; struct rlabel_setup labels; struct rrsvp_hop rsvp_hop; struct rsresv_parms sresv_parms; ; //Stat reservation data struct data_stat struct rlabel_setup labels; struct rlabel label; struct rrsvp_hop rsvp_hop; struct rsresv_parms sresv_parms; struct rerror_spec error_spec; ; Página 106/113
107 //Tear reservation data struct data_tear struct rlabel label; struct rrsvp_hop rsvp_hop; ; //Router Alert struct router_alert char opt1; char opt2; char opt3; char opt4; ; //Packet structure resv struct stream struct iphdr iph; struct router_alert ralert; struct rsvphead rhead; union struct data_resv_gs resv_gs; struct data_resv_af resv_af; struct data_refresh refresh; rdata; ; //Packet structure hop_by_hop struct streamh struct iphdr iph; struct rsvphead rhead; union struct data_stat stat; struct data_tear tear; rdata; ; union ubuffer struct stream pkt; struct streamh pkth; char data[sizeof(struct stream)]; ; struct if_names char name[if_namesize]; //mudar para ponteiro e usar malloc struct in_addr addr; ; struct my_ifreq char my_name[ifnamsiz]; union struct sockaddr_in my_addr; char my_data[512]; my_ifru; ; //Prototipos das funã ões utilizadas struct in_addr get_iface(struct in_addr); union rsvdata* make_localresv(union ucomapi*); int receive_from (union ubuffer*); int send_forward (union ubuffer*); union rsvdata* make_reservation (union ubuffer*); union rsvdata* refresh_reservation(union ubuffer*); union rsvdata* tear_reservation(union ubuffer*); union rsvdata* confirm_reservation(union ubuffer*, union rsvdata*); int send_stat_fail (union ubuffer*, union rsvdata*, int); int send_stat_ok (union ubuffer*, union rsvdata*); union rsvdata* insert_resv(union ubuffer*); int remove_resv(union rsvdata*); int for_me(union ubuffer*); int verify_label(union rsvdata*, union ubuffer*); int remove_resv_time(union rsvdata*); Página 107/113
108 int insert_resv_time(int time, union rsvdata*, char local); int next_resv_time(); int get_exp_time (); int send_refresh (union rsvdata*); int com_api (); int api_tear_reservation (union ucomapi*); int api_gs_reservation (union ucomapi*); int api_af_reservation (union ucomapi*); void *api_start_routine(void *); void sig_alarm(int); tcscript.h /*************************************************************************** * Copyright (C) 2005 by / * * [email protected] / [email protected] * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA , USA. * ***************************************************************************/ #include <ltcm/tc.h> #include <ltcm/tbf.h> #include <ltcm/util.h> #include <ltcm/cbq.h> #include <ltcm/u32.h> #include <ltcm/exception.h> #include <ltcm/dsmark.h> #include <ltcm/fifo.h> #include <ltcm/tcindex.h> #include <ltcm/prio.h> #include <ltcm/gred.h> #include <ltcm/police.h> #include <ltcm/filter.h> #include <ltcm/class.h> #include <ltcm/object.h> #include <iostream> using namespace std; using namespace ltcm; void default_tc(char *iface) try tc _tc; printf("iface:%s\n",iface); dev_interface dev(iface); //Apagar settings actuais qdisc *root; root = dev.get_root_qdisc(); try Página 108/113
109 root->delete_instance(); catch (const exception &tce) //Instalar dsmark na raiz //tc qdisc add dev $DEV root handle 1:0 dsmark indices 64 set_tc_index default_index 1 dsmark_qdisc dsmarkqd(64); dsmarkqd.set_handle(handle(1,0)); dsmarkqd.set_tc_index(true); dsmarkqd.set_default_index(0x1); dev << dsmarkqd; unsigned char priomap[] = 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ; //Adicionar Prio ao root //tc qdisc add dev $DEV parent 1:0 handle 2:0 prio bands 4 prio_qdisc prioqd(4, priomap); prioqd.set_handle(handle(2,0)); dsmarkqd << prioqd; //Adicionar tbf para GS ao prio //tc qdisc add dev $DEV parent 2:1 handle 21:0 tbf limit $GSLIMIT rate $GSRATE burst $GSBURST mtu $MTU tbf_qdisc tbf_gs; tbf_gs.set_handle(handle(0x21,0)); tbf_gs.set_limit(size::kb(100)); tbf_gs.set_mtu(1500); tbf_gs.set_burst(size::kb(5)); tbf_gs.set_mpu(64); tbf_gs.set_rate(rate::kbit(128)); prioqd.get_prio_class(1) << tbf_gs; //Adicionar tbf para canal de sinalizaã Ã o ao prio //tc qdisc add dev $DEV parent 2:2 handle 22:0 tbf limit $SIGLIMIT rate $SIGRATE burst $SIGBURST mtu $MTU tbf_qdisc tbf_sig; tbf_sig.set_handle(handle(0x22,0)); tbf_sig.set_limit(size::kb(100)); tbf_sig.set_mtu(1500); tbf_sig.set_burst(size::kb(5)); tbf_sig.set_mpu(64); tbf_sig.set_rate(rate::kbit(128)); prioqd.get_prio_class(2) << tbf_sig; //Adicionar gred para canal de AF ao prio //tc qdisc add dev $DEV parent 2:3 handle 23:0 gred setup DPs 3 default 3 grio gred_qdisc gredqd; gredqd.set_handle(handle(0x23,0)); gredqd.set_default_dp(3); gredqd.set_dp_count(3); gredqd.set_grio(true); prioqd.get_prio_class(3) << gredqd; //tc qdisc change dev $DEV parent 2:3 handle 23:0 gred limit $AFLIMIT min $AFMIN max $AFMAX avpkt $AVPKT burst $AFBURST bandwidth $LINKCAP DP 1 probability $AFPROB1 prio 2 gred_qdisc::dp &gred_chg1=(gredqd)[0]; gred_chg1.limit=rate::kbit(60); gred_chg1.min=rate::kbit(15); gred_chg1.max=rate::kbit(45); gred_chg1.avpkt=1540; gred_chg1.burst=20; gred_chg1.probability=0.01; gred_chg1.prio=2; gredqd.apply_dp(1, gred_chg1); //tc qdisc change dev $DEV parent 2:3 handle 23:0 gred limit $AFLIMIT min $AFMIN max $AFMAX avpkt $AVPKT burst $AFBURST bandwidth $LINKCAP DP 2 probability $AFPROB2 prio 3 gred_qdisc::dp &gred_chg2=(gredqd)[1]; gred_chg2.limit=rate::kbit(60); gred_chg2.min=rate::kbit(15); gred_chg2.max=rate::kbit(45); Página 109/113
110 gred_chg2.avpkt=1540; gred_chg2.burst=20; gred_chg2.probability=0.02; gred_chg2.prio=3; gredqd.apply_dp(2, gred_chg2); //tc qdisc change dev $DEV parent 2:3 handle 23:0 gred limit $AFLIMIT min $AFMIN max $AFMAX avpkt $AVPKT burst $AFBURST bandwidth $LINKCAP DP 3 probability $AFPROB3 prio 4 gred_qdisc::dp &gred_chg3=(gredqd)[2]; gred_chg3.limit=rate::kbit(60); gred_chg3.min=rate::kbit(15); gred_chg3.max=rate::kbit(45); gred_chg3.avpkt=1540; gred_chg3.burst=20; gred_chg3.probability=0.03; gred_chg3.prio=4; gredqd.apply_dp(3, gred_chg1); //Adicionar fifo para Best Efort //tc qdisc add dev $DEV parent 2:4 handle 24:0 pfifo limit $AVPKT fifo_qdisc fifo_be(fifo_qdisc::pfifo,1000); fifo_be.set_handle(handle(0x24,0)); fifo_be.set_limit(1000); prioqd.get_prio_class(4) << fifo_be; //Adicionar filtros default //tc filter add dev $DEV parent 1:0 protocol ip pref 1 tcindex mask 0xfc shift 2 pass_on //tc filter add dev $DEV parent 1:0 protocol ip pref 1 handle 0x2c tcindex classid 1:10 tcindex_filter filter1(1, protocol::get_by_name("ip")); filter1.set_hash(64); filter1.set_mask(0xf0); filter1.set_shift(2); filter1.set_fall_through(tcindex_filter::pass_on); filter1.set_handle(0x2c); filter1.set_flow(dsmarkqd.get_dsmark_class(0x10)); dsmarkqd << filter1; //tc filter add dev $DEV parent 1:0 protocol ip pref 2 tcindex mask 0xfc shift 2 pass_on tcindex_filter filter2(2, protocol::get_by_name("ip")); filter2.set_mask(0xfc); filter2.set_shift(2); filter2.set_fall_through(tcindex_filter::pass_on); // filter2.set_handle(0x22); // filter2.set_flow(dsmarkqd.get_dsmark_class(0x31)); dsmarkqd << filter2; //tc filter add dev $DEV parent 1:0 protocol ip pref 2 handle 0x22 tcindex classid 1:31 police rate $AF1RATE burst 256k mtu $MTU drop tcindex_filter filter3(2, protocol::get_by_name("ip")); filter3.set_handle(0x22); filter3.set_flow(dsmarkqd.get_dsmark_class(0x31)); filter3.use_police(true); police &po1=filter3.filter_police(); // po1.set_index(0xd); po1.set_rate(rate::mbit(10)); po1.set_maxburst(rate::kbps(128),-1); po1.set_minburst(1514, -1); po1.set_action(police::ok); // po1.set_mpu(48); // po1.set_avrate(rate::kbit(128)); // po1.set_peakrate(rate::mbit(10)); dsmarkqd << filter3; /* //tc filter add dev $DEV parent 1:0 protocol ip pref 2 handle 0x24 tcindex classid 1:32 police rate $AF2RATE burst 256k mtu $MTU drop tcindex_filter filter4(2, protocol::get_by_name("ip")); filter4.set_handle(0x24); police &po2=filter4.filter_police(); po2.set_action(police::ok); Página 110/113
111 po2.set_maxburst(1000,1); po2.set_rate(rate::mbps(1)); po2.set_mpu(1500); filter4.use_police(true); // dsmarkqd << filter4; //tc filter add dev $DEV parent 1:0 protocol ip pref 2 handle 0x26 tcindex classid 1:33 police rate $AF3RATE burst 256k mtu $MTU drop tcindex_filter filter5(2, protocol::get_by_name("ip")); filter5.set_handle(0x22); police &po=filter5.filter_police(); po.set_action(police::ok); po.set_maxburst(1000,1); po.set_rate(rate::mbps(1)); po.set_mpu(1500); filter5.use_police(true); // dsmarkqd << filter5; */ //tc filter add dev $DEV parent 2:0 protocol ip pref 1 tcindex mask 0xf0 shift 4 pass_on //tc filter add dev $DEV parent 2:0 protocol ip pref 1 handle 0x1 tcindex classid 2:1 tcindex_filter filter6(1, protocol::get_by_name("ip")); filter6.set_mask(0xf0); filter6.set_shift(4); filter6.set_fall_through(tcindex_filter::pass_on); filter6.set_handle(0x1); filter6.set_flow(prioqd.get_prio_class(1)); prioqd << filter6; //tc filter add dev $DEV parent 2:0 protocol ip pref 2 tcindex mask 0xf0 shift 4 pass_on //tc filter add dev $DEV parent 2:0 protocol ip pref 2 handle 0x3 tcindex classid 2:3 tcindex_filter filter7(2, protocol::get_by_name("ip")); filter7.set_mask(0xf0); filter7.set_shift(4); filter7.set_fall_through(tcindex_filter::pass_on); filter7.set_handle(0x3); filter7.set_flow(prioqd.get_prio_class(3)); prioqd << filter7; //tc filter add dev $DEV parent 2:0 protocol ip prio 3 u32 match ip tos 0x2e 0xff flowid 2:2 u32_filter filter8(3, protocol::get_by_name("ip")); u32_match_ip::match(filter8, u32_match_ip::tos, 0x2e, 0xff); filter8.set_flow(prioqd.get_prio_class(2)); prioqd << filter8; //tc filter add dev $DEV parent 2:0 protocol ip prio 4 u32 match ip tos 0x00 0x00 flowid 2:4 u32_filter filter9(4, protocol::get_by_name("ip")); u32_match_ip::match(filter9, u32_match_ip::tos, 0x0, 0x00); filter9.set_flow(prioqd.get_prio_class(4)); prioqd << filter9; catch (const tc_exception &e) cerr << "tc failure " << iface << ": " << e.what() << " (" << strerror(e.additional_error()) << ")" << endl; catch (const exception &tce) cerr << "failure " << iface << ": " << tce.what() << endl; return; return; ; srbq.h #include <netinet/in.h> #include <stdio.h> #include <unistd.h> #include <sys/socket.h> /* basic socket definitions */ #include <sys/types.h> /* basic system data types */ Página 111/113
112 #include <sys/un.h> /* for Unix domain sockets */ #include <errno.h> #include <arpa/inet.h> #include <stdlib.h> //Estrutura para comunicaã Ã o com API struct scomapi int pid; // pid do programa fonte char type; // tipo de reserva: 0 - apagar, 1 - GS, 2 - AF char tos; // tos associado ao fluxo unsigned int rex; // tempo de expiraã Ã o da reserva int port; // porta para o fluxo struct in_addr daddr; // endereã o de destino long opt1; // GS: token bucket rate, AF: degradation rate 1 long opt2; // GS: token bucket size, AF: degradation rate 2 long opt3; // GS: nao usado, AF: drop rate unsigned int label; // label da reserva - para enviar tear ; union ucomapi struct scomapi comapi; char buffer[sizeof(struct scomapi)]; ; //retorna o label da reserva unsigned int comm_rsvp_api(int, char, int, int, char *, long, long, long); srbq.c /*************************************************************************** * Copyright (C) 2005 by / * * [email protected] / [email protected] * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA , USA. * ***************************************************************************/ #define UNIXSTR_PATH "/tmp/unix.str" #define UNIXSTR_PATH2 "/tmp/unix2.str" #include <netinet/in.h> #include <stdio.h> #include <unistd.h> #include <sys/socket.h> /* basic socket definitions */ #include <sys/types.h> /* basic system data types */ #include <sys/un.h> /* for Unix domain sockets */ #include <errno.h> #include <arpa/inet.h> #include <stdlib.h> //Estrutura para comunicaã Ã o com API //Estrutura para comunicaã Ã o com API struct scomapi int pid; // pid do programa fonte char type; // tipo de reserva: 0 - apagar, 1 - GS, 2 - AF char tos; // tos associado ao fluxo unsigned int rex; // tempo de expiraã Ã o da reserva Página 112/113
113 int port; // porta para o fluxo struct in_addr daddr; // endereã o de destino long opt1; // GS: token bucket rate, AF: degradation rate 1 long opt2; // GS: token bucket size, AF: degradation rate 2 long opt3; // GS: nao usado, AF: drop rate unsigned int label; // label da reserva - para enviar tear ; union ucomapi struct scomapi comapi; char buffer[sizeof(struct scomapi)]; ; unsigned int comm_rsvp_api(int type, char tos, int rex, int port, char *daddr, long opt1, long opt2, long opt3) int sock, fromlen; struct sockaddr_un servaddr, cliaddr, from; /* Struct for the server socket address. */ union ucomapi sdata, rdata; sock = socket( AF_UNIX, SOCK_DGRAM, 0 ); /* Create the client's endpoint. */ unlink(unixstr_path2); bzero(&cliaddr, sizeof(cliaddr)); cliaddr.sun_family=af_unix; strcpy(cliaddr.sun_path, UNIXSTR_PATH2); bind(sock, (struct sockaddr *) &cliaddr, sizeof(cliaddr)); bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family=af_unix; strcpy(servaddr.sun_path, UNIXSTR_PATH); bzero(&sdata, sizeof(sdata)); sdata.comapi.pid=getpid(); sdata.comapi.type=type; sdata.comapi.tos=tos; sdata.comapi.rex=rex; sdata.comapi.port=port; sdata.comapi.daddr.s_addr=inet_addr(daddr); sdata.comapi.opt1=opt1; sdata.comapi.opt2=opt2; sendto(sock, sdata.buffer, sizeof(sdata), 0, (struct sockaddr *) &servaddr, sizeof(servaddr)); bzero(&rdata, sizeof(rdata)); recvfrom(sock, rdata.buffer, sizeof(rdata), 0, (struct sockaddr *) &from, &fromlen); close(sock); if (rdata.comapi.type==0) return(rdata.comapi.label); else return(0); Página 113/113
Serviços de Comunicações. Serviços de Comunicações. Módulo 7 Qualidade de Serviço em redes IP. condições de rede existentes em cada momento
Módulo 7 Qualidade de Serviço em redes IP 7.1. O porquê da Qualidade de Serviço 7.2. Mecanismos para QoS 7.3. Modelo de Serviços Integrados - IntServ 7.4. Modelo de Serviços Diferenciados - DiffServ 1
Serviços Diferenciados na Internet
Serviços Diferenciados na Internet FEUP/DEEC/RBL 2002/03 José Ruela Serviços Diferenciados na Internet O IETF desenvolveu um modelo de Serviços Diferenciados - Differentiated Services (DiffServ) - que
Qualidade de serviço. Determina o grau de satisfação do usuário em relação a um serviço específico Capacidade da rede de atender a requisitos de
Qualidade de serviço Determina o grau de satisfação do usuário em relação a um serviço específico Capacidade da rede de atender a requisitos de Vazão Atraso Variação do atraso Erros Outros Qualidade de
ICORLI. INSTALAÇÃO, CONFIGURAÇÃO e OPERAÇÃO EM REDES LOCAIS e INTERNET
INSTALAÇÃO, CONFIGURAÇÃO e OPERAÇÃO EM REDES LOCAIS e INTERNET 2010/2011 1 Protocolo TCP/IP É um padrão de comunicação entre diferentes computadores e diferentes sistemas operativos. Cada computador deve
Prof. Samuel Henrique Bucke Brito
- QoS e Engenharia de Tráfego www.labcisco.com.br ::: [email protected] Prof. Samuel Henrique Bucke Brito Introdução Em oposição ao paradigma best-effort (melhor esforço) da Internet, está crescendo
Arquitetura de Rede de Computadores
TCP/IP Roteamento Arquitetura de Rede de Prof. Pedro Neto Aracaju Sergipe - 2011 Ementa da Disciplina 4. Roteamento i. Máscara de Rede ii. Sub-Redes iii. Números Binários e Máscara de Sub-Rede iv. O Roteador
Protocolos em Redes de Dados. Enquadramento histórico. Modo de funcionamento FEC. Antecedentes IP Switching Tag Switching. Exemplo de.
Multiprotocol Label Switching Aula 07 FCUL 2005-20056 Objectivo: Conciliar as tecnologias baseadas em comutação (switching) com o encaminhamento IP. Aplicações: Aumentar o desempenho. Engenharia de tráfego.
Aula 08 MPLS 2004-2005 FCUL. Protocolos em Redes de Dados. Luís Rodrigues. Enquadramento. Modo de funcionamento. Antecedentes MPLS.
Aula 08 FCUL 2004-2005 Multiprotocol Label Switching Objectivo: Conciliar as tecnologias baseadas em comutação (switching) com o encaminhamento IP. Aplicações: Aumentar o desempenho. Engenharia de tráfego.
TRANSMISSÃO DE DADOS Prof. Ricardo Rodrigues Barcelar http://www.ricardobarcelar.com
- Aula 5-1. A CAMADA DE TRANSPORTE Parte 1 Responsável pela movimentação de dados, de forma eficiente e confiável, entre processos em execução nos equipamentos conectados a uma rede de computadores, independentemente
Entendendo como funciona o NAT
Entendendo como funciona o NAT Vamos inicialmente entender exatamente qual a função do NAT e em que situações ele é indicado. O NAT surgiu como uma alternativa real para o problema de falta de endereços
04.03 Quality of Service (QoS)
04.03 Quality of Service (QoS) Redes de Serviços e Comunicações Multimédia RSCM/ISEL-DEETC-SRC/2004 1 Necessidade de QoS Uma medida colectiva da qualidade de serviço Para uma aplicação Critérios: Disponibilidade
Gerenciamento de redes
Gerenciamento de redes Gerenciamento de Serviços Gerenciamento de QoS (Qualidade de serviço) slide 1 Qualidade de serviços: aplicações de multimídia: áudio e vídeo de rede ( mídia contínua ) QoS rede oferece
QoS em Redes IP: Arquitetura e Aplicações
QoS em Redes IP: Arquitetura e Aplicações Mário Meireles Teixeira [email protected] Motivação Atualmente, funcionam sobre as redes IP aplicações cujos requisitos elas não foram projetadas para atender
Relatório do 2º Guião Laboratorial de Avaliação: Encaminhamento de pacotes. Licenciatura: ETI Turma : ETC1 Grupo : rd2_t3_02 Data: 30/10/2009
Licenciaturas em Informática e Gestão de Empresas, Engenharia de Telecomunicações e Informática e Engenharia Informática Redes Digitais II Relatório do 2º Guião Laboratorial de Avaliação: Encaminhamento
MÓDULO 7 Modelo OSI. 7.1 Serviços Versus Protocolos
MÓDULO 7 Modelo OSI A maioria das redes são organizadas como pilhas ou níveis de camadas, umas sobre as outras, sendo feito com o intuito de reduzir a complexidade do projeto da rede. O objetivo de cada
Um sistema SMS 1 simplificado
1 Introdução Um sistema SMS 1 simplificado Projecto de Redes de Computadores I - 2007/2008 LEIC IST, Tagus Park 10 de Setembro de 2007 Pretende-se com este projecto que os alunos implementem um sistema
Módulo 8 Ethernet Switching
CCNA 1 Conceitos Básicos de Redes Módulo 8 Ethernet Switching Comutação Ethernet 2 Segmentação de Redes Numa Ethernet o meio de transmissão é compartilhado Só um nó pode transmitir de cada vez. O aumento
Multiprotocol Label Switching. Protocolos em Redes de Dados- Aula 08 -MPLS p.4. Motivação: desempenho. Enquadramento histórico
Multiprotocol Label Switching Protocolos em Redes de Dados - Aula 08 - MPLS Luís Rodrigues [email protected] DI/FCUL Objectivo: Conciliar as tecnologias baseadas em comutação (switching) com o encaminhamento
Gestão dos Níveis de Serviço
A Gestão dos Níveis de Serviço (SLM) Os sistemas e tecnologias de informação e comunicação têm nas empresas um papel cada vez mais importante evoluindo, hoje em dia, para níveis mais elevados de funcionamento
Rede de Computadores II
Rede de Computadores II Slide 1 Roteamento Determinar o melhor caminho a ser tomado da origem até o destino. Se utiliza do endereço de destino para determinar a melhor rota. Roteador default, é o roteador
Há dois tipos de configurações bidirecionais usados na comunicação em uma rede Ethernet:
Comunicação em uma rede Ethernet A comunicação em uma rede local comutada ocorre de três formas: unicast, broadcast e multicast: -Unicast: Comunicação na qual um quadro é enviado de um host e endereçado
4 Arquitetura básica de um analisador de elementos de redes
4 Arquitetura básica de um analisador de elementos de redes Neste capítulo é apresentado o desenvolvimento de um dispositivo analisador de redes e de elementos de redes, utilizando tecnologia FPGA. Conforme
1 INTRODUÇÃO Internet Engineering Task Force (IETF) Mobile IP
1 INTRODUÇÃO Devido ao crescimento da Internet, tanto do ponto de vista do número de usuários como o de serviços oferecidos, e o rápido progresso da tecnologia de comunicação sem fio (wireless), tem se
Plano de endereçamento IPv6 da RCTS
Plano de endereçamento IPv6 da RCTS Linhas Gerais de Funcionamento do LIR IPv6 PT.RCCN I. Introdução A FCCN tem mantido nos últimos anos um projecto de acompanhamento dos desenvolvimentos efectuados sobre
Protocolo TCP/IP. Neste caso cada computador da rede precisa de, pelo menos, dois parâmetros configurados:
Protocolo TCP/IP Neste caso cada computador da rede precisa de, pelo menos, dois parâmetros configurados: Número IP Máscara de sub-rede O Número IP é um número no seguinte formato: x.y.z.w Não podem existir
A camada de rede do modelo OSI
A camada de rede do modelo OSI 1 O que faz a camada de rede? (1/2) Esta camada tem como função principal fazer o endereçamento de mensagens. o Estabelece a relação entre um endereço lógico e um endereço
Funções específicas de cada camada do modelo OSI da ISO.
Funções específicas de cada camada do modelo OSI da ISO. 1ª Camada - Física - Grupo Rede Física Esta camada traduz os bits a enviar em sinais elétricos, de tensão ou corrente. Ela fornece os meios de hardware
Márcio Leandro Moraes Rodrigues. Frame Relay
Márcio Leandro Moraes Rodrigues Frame Relay Introdução O frame relay é uma tecnologia de chaveamento baseada em pacotes que foi desenvolvida visando exclusivamente a velocidade. Embora não confiável, principalmente
3 SCS: Sistema de Componentes de Software
3 SCS: Sistema de Componentes de Software O mecanismo para acompanhamento das chamadas remotas se baseia em informações coletadas durante a execução da aplicação. Para a coleta dessas informações é necessário
Redes de Computadores. Trabalho de Laboratório Nº7
Redes de Computadores Curso de Eng. Informática Curso de Eng. de Electrónica e Computadores Trabalho de Laboratório Nº7 Análise do tráfego na rede Protocolos TCP e UDP Objectivo Usar o Ethereal para visualizar
GESTÃO DE SISTEMAS E REDES YNAMIC HOST CONFIGURATION PROTOCOL
GESTÃO DE SISTEMAS E REDES YNAMIC HOST CONFIGURATION PROTOCOL OUTLINE DHCP PROTOCOLO RELAY AGENT EXEMPLO LINUX EXEMPLO IOS DHCP Dynamic Host Configuration Protocol, ou DHCP, é um dos protocolos de suporte
Capítulo 4 - Roteamento e Roteadores
Capítulo 4 - Roteamento e Roteadores 4.1 - Roteamento Roteamento é a escolha do módulo do nó de origem ao nó de destino por onde as mensagens devem transitar. Na comutação de circuito, nas mensagens ou
Qualidade de Serviço Requisitos das aplicações Técnicas para obter boa qualidade de serviço Sobredimensionamento rede Memorização pacotes
Qualidade de Serviço Requisitos das aplicações Técnicas para obter boa qualidade de serviço Sobredimensionamento da rede Memorização de pacotes Suavização do tráfego (Traffic shaping) O algoritmo Leaky
Redes de Computadores II INF-3A
Redes de Computadores II INF-3A 1 ROTEAMENTO 2 Papel do roteador em uma rede de computadores O Roteador é o responsável por encontrar um caminho entre a rede onde está o computador que enviou os dados
ADDRESS RESOLUTION PROTOCOL. Thiago de Almeida Correia
ADDRESS RESOLUTION PROTOCOL Thiago de Almeida Correia São Paulo 2011 1. Visão Geral Em uma rede de computadores local, os hosts se enxergam através de dois endereços, sendo um deles o endereço Internet
Ferramentas de Modelação e Análise de Sistemas baseadas em Redes de Petri (RdP)
Ferramentas de Modelação e Análise de Sistemas baseadas em Redes de Petri (RdP) Existem inúmeras ferramentas (software) baseadas em RdP que permitem desenvolver modelar e analisar sistema de RdP. Algumas
REDES DE COMPUTADORES I 2007/2008 LEIC - Tagus-Park TPC Nº 1. Avaliação sumário da matéria do capítulo 1
REDES DE COMPUTADORES I 007/008 LEIC - Tagus-Park TPC Nº 1 Avaliação sumário da matéria do capítulo 1 Pergunta: 1 1. Que tipo de Elemento de Rede é um Cliente? 1 Sistema Terminal ou Host Servidor 3 Encaminhador
Programação de Sistemas
Programação de Sistemas Introdução à gestão de memória Programação de Sistemas Gestão de memória : 1/16 Introdução (1) A memória central de um computador é escassa. [1981] IBM PC lançado com 64KB na motherboard,
MPLS MultiProtocol Label Switching
MPLS MultiProtocol Label Switching Cenário Atual As novas aplicações que necessitam de recurso da rede são cada vez mais comuns Transmissão de TV na Internet Videoconferências Jogos on-line A popularização
Modelo Cascata ou Clássico
Modelo Cascata ou Clássico INTRODUÇÃO O modelo clássico ou cascata, que também é conhecido por abordagem top-down, foi proposto por Royce em 1970. Até meados da década de 1980 foi o único modelo com aceitação
IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira
IFPE Disciplina: Sistemas Operacionais Prof. Anderson Luiz Moreira SERVIÇOS OFERECIDOS PELOS SOS 1 Introdução O SO é formado por um conjunto de rotinas (procedimentos) que oferecem serviços aos usuários
Além do melhor esforço
Além do melhor esforço Redes Multimídia Prof. Emerson Ribeiro de Mello Instituto Federal de Santa Catarina IFSC campus São José [email protected] 25 de agosto de 2011 1 / 42 Sumário 1 Além do melhor esforço
Interconexão de redes locais. Repetidores. Pontes (Bridges) Hubs. Pontes (Bridges) Pontes (Bridges) Existência de diferentes padrões de rede
Interconexão de redes locais Existência de diferentes padrões de rede necessidade de conectá-los Interconexão pode ocorrer em diferentes âmbitos LAN-LAN LAN: gerente de um determinado setor de uma empresa
Qualidade em Servicos de Rede Prof. Eduardo Maronas Monks Roteiro de Laboratorio Camada de Transporte Parte II
Qualidade em Servicos de Rede Prof. Eduardo Maronas Monks Roteiro de Laboratorio Camada de Transporte Parte II 1) Explicar os seguintes mecanismos e conceitos do protocolo TCP: 1. Slow Start O algoritmo
A Gestão, os Sistemas de Informação e a Informação nas Organizações
Introdução: Os Sistemas de Informação (SI) enquanto assunto de gestão têm cerca de 30 anos de idade e a sua evolução ao longo destes últimos anos tem sido tão dramática como irregular. A importância dos
MRP II. Planejamento e Controle da Produção 3 professor Muris Lage Junior
MRP II Introdução A lógica de cálculo das necessidades é conhecida há muito tempo Porém só pode ser utilizada na prática em situações mais complexas a partir dos anos 60 A partir de meados da década de
Na Figura a seguir apresento um exemplo de uma "mini-tabela" de roteamento:
Tutorial de TCP/IP - Parte 6 - Tabelas de Roteamento Por Júlio Cesar Fabris Battisti Introdução Esta é a sexta parte do Tutorial de TCP/IP. Na Parte 1 tratei dos aspectos básicos do protocolo TCP/IP. Na
Tabela de roteamento
Existem duas atividades que são básicas a um roteador. São elas: A determinação das melhores rotas Determinar a melhor rota é definir por qual enlace uma determinada mensagem deve ser enviada para chegar
NOTA DE ESCLARECIMENTO
NOTA DE ESCLARECIMENTO SOBRE A UTILIZAÇÃO DE NUMERAÇÃO GEOGRÁFICA EM REDES PRIVATIVAS MULTI-SITE I ENQUADRAMENTO O ICP-ANACOM ao acompanhar a evolução tecnológica e tendo sido confrontado com um pedido
Gerência de Processador
Gerência de Processador Prof. Edwar Saliba Júnior Junho de 2009 Unidade 03-003 Gerência de Processador 1 Introdução Com o surgimento dos sistemas multiprogramáveis, onde múltiplos processos poderiam permanecer
Arquitetura de Computadores II
Universidade Federal do Rio de Janeiro Informática DCC/IM Arquitetura de Computadores II Sistemas de Troca de Mensagens O Sistema de Comunicação provê tipicamente os seguintes serviços para as aplicações:
Processos e Threads (partes I e II)
Processos e Threads (partes I e II) 1) O que é um processo? É qualquer aplicação executada no processador. Exe: Bloco de notas, ler um dado de um disco, mostrar um texto na tela. Um processo é um programa
TRANSMISSÃO DE DADOS Prof. Ricardo Rodrigues Barcelar http://www.ricardobarcelar.com
- Aula 3-1. A CAMADA DE REDE (Parte 1) A camada de Rede está relacionada à transferência de pacotes da origem para o destino. No entanto, chegar ao destino pode envolver vários saltos em roteadores intermediários.
1.1 Transmissão multimídia em redes
1.1 Transmissão multimídia em redes Pode-se dividir a parte de transmissão multimídia em redes de computadores como mostra a figura 1, ou seja, a parte de conferência (que requer interatividade) e a parte
A memória é um recurso fundamental e de extrema importância para a operação de qualquer Sistema Computacional; A memória trata-se de uma grande
A memória é um recurso fundamental e de extrema importância para a operação de qualquer Sistema Computacional; A memória trata-se de uma grande região de armazenamento formada por bytes ou palavras, cada
CAPÍTULO 2 CARACTERÍSTICAS DE E/S E PORTA PARALELA
8 CAPÍTULO 2 CARACTERÍSTICAS DE E/S E PORTA PARALELA A porta paralela, também conhecida por printer port ou Centronics e a porta serial (RS-232) são interfaces bastante comuns que, apesar de estarem praticamente
FICHA INFORMATIVA E DE TRABALHO MÓDULO 0773 - REDE LOCAL INSTALAÇÃO
CURSO EFA 2012 / 2013 Formando: Data: / / ÁREA/Assunto: Formador / Mediador: Avaliação Formando Formador FICHA INFORMATIVA E DE TRABALHO MÓDULO 0773 - REDE LOCAL INSTALAÇÃO Standard IEE 802 Para que as
Prof. Samuel Henrique Bucke Brito
- Switch na Camada 2: Comutação www.labcisco.com.br ::: [email protected] Prof. Samuel Henrique Bucke Brito Introdução A conexão entre duas portas de entrada e saída, bem como a transferência de
MODELOS DE QUALIDADE DE SERVIÇO - APLICAÇÕES EM IP
MODELOS DE QUALIDADE DE SERVIÇO - APLICAÇÕES EM IP Nilton Alves Júnior [email protected] Kelly Soyan Pires Dominguez [email protected] Resumo Este trabalho tem como função explicitar o conceito de Qualidade de Serviço
Redes de Computadores II. Professor Airton Ribeiro de Sousa
Redes de Computadores II Professor Airton Ribeiro de Sousa 1 PROTOCOLO IP IPv4 - Endereçamento 2 PROTOCOLO IP IPv4 - Endereçamento A quantidade de endereços possíveis pode ser calculada de forma simples.
Mecanismos de QoS em Linux Hierarchical Token Bucket (HTB)
Mecanismos de QoS em Linux Hierarchical Token Bucket (HTB) Este roteiro descreve um cenário prático onde o algoritmo Hierarchical Token Bucket (HTB) é utilizado para criar uma política de QoS flexível,
Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO
Conceitos básicos e serviços do Sistema Operacional Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO Tipos de serviço do S.O. O S.O.
Programação 2ºSemestre MEEC - 2010/2011. Programação 2º Semestre 2010/2011 Enunciado do projecto
Mestrado Integrado em Engenharia Electrotécnica e de Computadores Programação 2º Semestre 2010/2011 Enunciado do projecto O projecto a desenvolver pelos alunos consistirá numa sistema de monitorização,
Tecnologia de Redes de Computadores - aula 5
Tecnologia de Redes de Computadores - aula 5 Prof. Celso Rabelo Centro Universitário da Cidade 1 Objetivo 2 3 4 IGPxEGP Vetor de Distância Estado de Enlace Objetivo Objetivo Apresentar o conceito de. Conceito
Veja abaixo um exemplo de um endereço IP de 32 bits: 10000011 01101011 00010000 11001000
4 Camada de Rede: O papel da camada de rede é transportar pacotes de um hospedeiro remetente a um hospedeiro destinatário. Para fazê-lo, duas importantes funções da camada de rede podem ser identificadas:
Diagrama de transição de Estados (DTE)
Diagrama de transição de Estados (DTE) O DTE é uma ferramenta de modelação poderosa para descrever o comportamento do sistema dependente do tempo. A necessidade de uma ferramenta deste tipo surgiu das
SIMULADOR DE ROTEAMENTO DE PACOTES (V. 3 20/05/2010)
SIMULADOR DE ROTEAMENTO DE PACOTES (V. 3 20/05/2010) OBJETIVO GERAL Este trabalho possui o objetivo de exercitar a lógica de programação dos alunos do Terceiro ano do Curso de BSI e também desenvolver
Prof. Marcelo Machado Cunha Parte 3 www.marcelomachado.com
Prof. Marcelo Machado Cunha Parte 3 www.marcelomachado.com Protocolo é a linguagem usada pelos dispositivos de uma rede de modo que eles consigam se comunicar Objetivo Transmitir dados em uma rede A transmissão
Sistemas Distribuídos. Aleardo Manacero Jr.
Sistemas Distribuídos Aleardo Manacero Jr. Conteúdo Conceitos fundamentais Estratégias de controle: relógios e algoritmos de sincronismo Serviços: arquivos e memória Corba Processamento distribuído Sistemas
PROJETO DE REDES www.projetoderedes.com.br
PROJETO DE REDES www.projetoderedes.com.br CENTRO UNIVERSITÁRIO DE VOLTA REDONDA UniFOA Curso Tecnológico de Redes de Computadores Disciplina: Redes Convergentes II Professor: José Maurício S. Pinheiro
COMPONENTES BÁSICOS DE
COMPONENTES BÁSICOS DE REDES 2ºPARTE Prof. Me. Hélio Esperidião SWITCH O SWITCH opera de forma mais inteligente. Ele analisa os pacotes de dados que chegam a ele e descobre os endereços de origem e destino.
SISTEMAS DISTRIBUÍDOS
SISTEMAS DISTRIBUÍDOS Modelo cliente e servidor Slide 2 Nielsen C. Damasceno Modelos Cliente - Servidor A principal diferença entre um sistema centralizado e um sistema distribuído está na comunicação
Redes de Computadores
Redes de Computadores Prof. Marcelo Gonçalves Rubinstein Programa de Pós-Graduação em Engenharia Eletrônica Faculdade de Engenharia Universidade do Estado do Rio de Janeiro Ementa Introdução a Redes de
UNIVERSIDADE. Sistemas Distribuídos
UNIVERSIDADE Sistemas Distribuídos Ciência da Computação Prof. Jesus José de Oliveira Neto Comunicação Inter-Processos Sockets e Portas Introdução Sistemas distribuídos consistem da comunicação entre processos
Sistemas Distribuídos
Sistemas Distribuídos Modelo Cliente-Servidor: Introdução aos tipos de servidores e clientes Prof. MSc. Hugo Souza Iniciando o módulo 03 da primeira unidade, iremos abordar sobre o Modelo Cliente-Servidor
Redes de Comunicações Capítulo 6.1
Capítulo 6.1 6.1 - Técnicas de Comutação 1 WAN s Wide Area Networks Uma WAN é uma rede dispersa por uma grande área física, sob o controlo de uma administração única e baseada em circuitos dedicados (exemplo:
APLICAÇÃO REDE APLICAÇÃO APRESENTAÇÃO SESSÃO TRANSPORTE REDE LINK DE DADOS FÍSICA 1/5 PROTOCOLOS DE REDE
1/5 PROTOCOLOS DE O Modelo OSI O OSI é um modelo usado para entender como os protocolos de rede funcionam. Para facilitar a interconexão de sistemas de computadores, a ISO (International Standards Organization)
Processo do Serviços de Manutenção de Sistemas de Informação
Processo do Serviços de Manutenção de Sistemas de Informação 070112=SINFIC HM Processo Manutencao MSI.doc, Página 1 Ex.mo(s) Senhor(es): A SINFIC agradece a possibilidade de poder apresentar uma proposta
MPLS Multi-Protocol Label Switching
MPLS Multi-Protocol Label Switching Adilson Eduardo Guelfi Volnys Borges Bernal Luis Gustavo G. Kiatake Agenda Introdução Arquitetura de Rede Conceitos MPLS Conclusões Introdução MPLS is the enabling technology
Serviços Diferenciados em Sistemas Operacionais Linux
Universidade Federal de Santa Catarina UFSC Programa de Pós Graduação em Ciências da Computação PPGCC Disciplina: Sistemas Operaciaonais Aluno: Luiz Henrique Vicente Serviços Diferenciados em Sistemas
Manual do Gestor da Informação do Sistema
Faculdade de Engenharia da Universidade do Porto Licenciatura Informática e Computação Laboratório de Informática Avançada Automatização de Horários Manual do Gestor da Informação do Sistema João Braga
Serviços de Comunicações RELATÓRIO LABORATORIAL IMPLEMENTAÇÃO DE SOLUÇÃO IP PBX
Serviços de Comunicações RELATÓRIO LABORATORIAL IMPLEMENTAÇÃO DE SOLUÇÃO IP PBX 19 de Dezembro de 2014 Carlos Leocádio - [email protected] Tiago Ferreira - [email protected] Departamento de Engenharia Electrotécnica
CAP. I ERROS EM CÁLCULO NUMÉRICO
CAP. I ERROS EM CÁLCULO NUMÉRICO 0. Introdução Por método numérico entende-se um método para calcular a solução de um problema realizando apenas uma sequência finita de operações aritméticas. A obtenção
SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2
SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2 1.1 Introdução... 2 1.2 Estrutura do IP... 3 1.3 Tipos de IP... 3 1.4 Classes de IP... 4 1.5 Máscara de Sub-Rede... 6 1.6 Atribuindo um IP ao computador... 7 2
Tarefa Orientada 16 Vistas
Tarefa Orientada 16 Vistas Objectivos: Vistas só de leitura Vistas de manipulação de dados Uma vista consiste numa instrução de SELECT que é armazenada como um objecto na base de dados. Deste modo, um
CONCURSO PÚBLICO ANALISTA DE SISTEMA ÊNFASE GOVERNANÇA DE TI ANALISTA DE GESTÃO RESPOSTAS ESPERADAS PRELIMINARES
CELG DISTRIBUIÇÃO S.A EDITAL N. 1/2014 CONCURSO PÚBLICO ANALISTA DE GESTÃO ANALISTA DE SISTEMA ÊNFASE GOVERNANÇA DE TI RESPOSTAS ESPERADAS PRELIMINARES O Centro de Seleção da Universidade Federal de Goiás
Redes de Computadores (RCOMP 2014/2015)
Redes de Computadores (RCOMP 2014/2015) Transmissão de Dados Digitais Comunicação em rede 1 Transmissão de dados Objetivo: transportar informação mesmo que fosse usado um meio de transporte clássico seria
ENHANCED SERVER FAULT- TOLERANCE FOR IMPROVED USER EXPERIENCE. André Esteves nº3412 David Monteiro
ENHANCED SERVER FAULT- TOLERANCE FOR IMPROVED USER EXPERIENCE André Esteves nº3412 David Monteiro INTRODUÇÃO É proposto uma arquitectura de servidor Web dividida que tolera perfeitamente tanto falhas na
Rede de Computadores
Escola de Ciências e Tecnologia UFRN Rede de Computadores Prof. Aquiles Burlamaqui Nélio Cacho Luiz Eduardo Eduardo Aranha ECT1103 INFORMÁTICA FUNDAMENTAL Manter o telefone celular sempre desligado/silencioso
Redes e Telecomunicações
Redes e Telecomunicações Comunicação Processo pelo qual uma informação gerada num ponto (origem) é transferida para outro ponto (destino) Telecomunicações Telecomunicação do grego: tele = distância do
Endereços Lógicos, Físicos e de Serviço
Endereçamento IP O IP é um protocolo da Camada de rede É um endereço lógico único em toda a rede, portanto, quando estamos navegando na Internet estamos utilizando um endereço IP único mundialmente, pois
Redes de Computadores
Redes de Computadores Técnicas de comutação Escola Superior de Tecnologia e Gestão Instituto Politécnico de Bragança Maio de 2006 WAN s Wide Area Networks Uma WAN é uma rede dispersa por uma grande área
Sistemas distribuídos:comunicação
M. G. Santos [email protected] Faculdade Câmara Cascudo - Estácio de Sá 16 de abril de 2010 Formas de comunicação Produtor-consumidor: comunicação uni-direccional, com o produtor entregando ao consumidor.
