Universidade de Aveiro

Tamanho: px
Começar a partir da página:

Download "Universidade de Aveiro"

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

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

Leia mais

Serviços Diferenciados na Internet

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

Leia mais

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 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

Leia mais

ICORLI. INSTALAÇÃO, CONFIGURAÇÃO e OPERAÇÃO EM REDES LOCAIS e INTERNET

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

Leia mais

Prof. Samuel Henrique Bucke Brito

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

Leia mais

Arquitetura de Rede de Computadores

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

Leia mais

Protocolos em Redes de Dados. Enquadramento histórico. Modo de funcionamento FEC. Antecedentes IP Switching Tag Switching. Exemplo de.

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.

Leia mais

Aula 08 MPLS 2004-2005 FCUL. Protocolos em Redes de Dados. Luís Rodrigues. Enquadramento. Modo de funcionamento. Antecedentes MPLS.

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.

Leia mais

TRANSMISSÃO DE DADOS Prof. Ricardo Rodrigues Barcelar http://www.ricardobarcelar.com

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

Leia mais

Entendendo como funciona o NAT

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

Leia mais

04.03 Quality of Service (QoS)

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

Leia mais

Gerenciamento de redes

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

Leia mais

QoS em Redes IP: Arquitetura e Aplicações

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

Leia mais

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

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

Leia mais

MÓDULO 7 Modelo OSI. 7.1 Serviços Versus Protocolos

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

Leia mais

Um sistema SMS 1 simplificado

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

Leia mais

Módulo 8 Ethernet Switching

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

Leia mais

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 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

Leia mais

Gestão dos Níveis de Serviço

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

Leia mais

Rede de Computadores II

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

Leia mais

Há dois tipos de configurações bidirecionais usados na comunicação em uma rede Ethernet:

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

Leia mais

4 Arquitetura básica de um analisador de elementos de redes

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

Leia mais

1 INTRODUÇÃO Internet Engineering Task Force (IETF) Mobile IP

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

Leia mais

Plano de endereçamento IPv6 da RCTS

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

Leia mais

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: 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

Leia mais

A camada de rede do modelo OSI

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

Leia mais

Funções específicas de cada camada do modelo OSI da ISO.

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

Leia mais

Márcio Leandro Moraes Rodrigues. Frame Relay

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

Leia mais

3 SCS: Sistema de Componentes de Software

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

Leia mais

Redes de Computadores. Trabalho de Laboratório Nº7

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

Leia mais

GESTÃO DE SISTEMAS E REDES YNAMIC HOST CONFIGURATION PROTOCOL

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

Leia mais

Capítulo 4 - Roteamento e Roteadores

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

Leia mais

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 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

Leia mais

Redes de Computadores II INF-3A

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

Leia mais

ADDRESS RESOLUTION PROTOCOL. Thiago de Almeida Correia

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

Leia mais

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) 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

Leia mais

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 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

Leia mais

Programação de Sistemas

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,

Leia mais

MPLS MultiProtocol Label Switching

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

Leia mais

Modelo Cascata ou Clássico

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

Leia mais

IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira

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

Leia mais

Além do melhor esforço

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

Leia mais

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. 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

Leia mais

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 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

Leia mais

A Gestão, os Sistemas de Informação e a Informação nas Organizações

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

Leia mais

MRP II. Planejamento e Controle da Produção 3 professor Muris Lage Junior

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

Leia mais

Na Figura a seguir apresento um exemplo de uma "mini-tabela" de roteamento:

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

Leia mais

Tabela de roteamento

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

Leia mais

NOTA DE ESCLARECIMENTO

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

Leia mais

Gerência de Processador

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

Leia mais

Arquitetura de Computadores II

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:

Leia mais

Processos e Threads (partes I e II)

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

Leia mais

TRANSMISSÃO DE DADOS Prof. Ricardo Rodrigues Barcelar http://www.ricardobarcelar.com

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.

Leia mais

1.1 Transmissão multimídia em redes

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

Leia mais

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 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

Leia mais

CAPÍTULO 2 CARACTERÍSTICAS DE E/S E PORTA PARALELA

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

Leia mais

FICHA INFORMATIVA E DE TRABALHO MÓDULO 0773 - REDE LOCAL INSTALAÇÃO

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

Leia mais

Prof. Samuel Henrique Bucke Brito

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

Leia mais

MODELOS DE QUALIDADE DE SERVIÇO - APLICAÇÕES EM IP

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

Leia mais

Redes de Computadores II. Professor Airton Ribeiro de Sousa

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.

Leia mais

Mecanismos de QoS em Linux Hierarchical Token Bucket (HTB)

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,

Leia mais

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

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.

Leia mais

Programação 2ºSemestre MEEC - 2010/2011. Programação 2º Semestre 2010/2011 Enunciado do projecto

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,

Leia mais

Tecnologia de Redes de Computadores - aula 5

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

Leia mais

Veja abaixo um exemplo de um endereço IP de 32 bits: 10000011 01101011 00010000 11001000

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:

Leia mais

Diagrama de transição de Estados (DTE)

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

Leia mais

SIMULADOR DE ROTEAMENTO DE PACOTES (V. 3 20/05/2010)

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

Leia mais

Prof. Marcelo Machado Cunha Parte 3 www.marcelomachado.com

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

Leia mais

Sistemas Distribuídos. Aleardo Manacero Jr.

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

Leia mais

PROJETO DE REDES www.projetoderedes.com.br

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

Leia mais

COMPONENTES BÁSICOS DE

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.

Leia mais

SISTEMAS DISTRIBUÍDOS

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

Leia mais

Redes de Computadores

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

Leia mais

UNIVERSIDADE. Sistemas Distribuídos

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

Leia mais

Sistemas Distribuídos

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

Leia mais

Redes de Comunicações Capítulo 6.1

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:

Leia mais

APLICAÇÃO REDE APLICAÇÃO APRESENTAÇÃO SESSÃO TRANSPORTE REDE LINK DE DADOS FÍSICA 1/5 PROTOCOLOS DE REDE

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)

Leia mais

Processo do Serviços de Manutenção de Sistemas de Informação

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

Leia mais

MPLS Multi-Protocol Label Switching

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

Leia mais

Serviços Diferenciados em Sistemas Operacionais Linux

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

Leia mais

Manual do Gestor da Informação do Sistema

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

Leia mais

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 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

Leia mais

CAP. I ERROS EM CÁLCULO NUMÉRICO

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

Leia mais

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2

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

Leia mais

Tarefa Orientada 16 Vistas

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

Leia mais

CONCURSO PÚBLICO ANALISTA DE SISTEMA ÊNFASE GOVERNANÇA DE TI ANALISTA DE GESTÃO RESPOSTAS ESPERADAS PRELIMINARES

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

Leia mais

Redes de Computadores (RCOMP 2014/2015)

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

Leia mais

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 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

Leia mais

Rede de Computadores

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

Leia mais

Redes e Telecomunicações

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

Leia mais

Endereços Lógicos, Físicos e de Serviço

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

Leia mais

Redes de Computadores

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

Leia mais

Sistemas distribuídos:comunicação

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.

Leia mais