Estrutura Interna - Classes Kalina Ramos Porto 08/08/2003 Roteiro Nodos Endereçamento Formato de Pacotes Filas e escalonamento de pacotes Agentes Aplicações e Geradores de Tráfego Nodo n0 Port Classifier Addr Classifier Node entry dmux_ entry_ n1 Unicast Node Multicast Node classifier_ Node entry entry_ classifier_ dmux_ Multicast Classifier multiclassifier_ set n0 [ns_ node] set ns_ [new Simulator –multicast on] set n1 [ns_ node] Classificadores Classificadores são responsáveis por encaminhar pacotes para outros objetos de simulação de acordo com um critério lógico. Cada classificador contém uma tabela de objetos de simulação indexados por números de slot. Os classificadores determinam o número de slot (de acordo com um critério lógico) associado com o pacote recebido e o encaminham para o objeto indexado pelo número de slot específico. Endereçamento Dois estilos básicos de endereçamento disponíveis: flat e hierárquico Endereço flat padrão: 32 bits para o id do nodo e 32 bits para o id da porta Endereço hierárquico padrão: 3 níveis de hierarquia 10 11 11 ou 1 9 11 11 se multicast é especificado 32 bits para o id da porta Endereçamento (Cont.) O seguinte comando é utilizado para especificar endereçamento hierárquico: $ns set-address-format hierarchical O comando anterior permite configurar diferentes números de níveis hierárquicos com seus respectivos números de bits: $ns set-address-format hierarchical <# níveis hierárquicos> <# bits para nível 1> ... <# bits para o nível n> Exemplo: $ns set-address-format hierarchical 2 8 15 Nodo Hierárquico n2 Address classifier Node entry To Port demux Level 3 Level 1 Level 2 Utilizando Endereçamento Hierárquico Habilita-se o modo hierárquico: $ns set-address-format hierarchical Definem-se o número de domínios, o número de clusters em cada domínio e o número de nodos em cada cluster: AddrParams set domain_num_ 2 lappend cluster_num 2 2 AddrParams set cluster_num_ $cluster_num lappend eilastlevel 2 3 2 3 AddrParams set nodes_num_ $eilastlevel Criam-se os nodos com os endereços hierárquicos: $ns node 0.0.1 Formato De Pacotes Objetos da classe Packet são a unidade fundamental de troca entre objetos na simulação. A classe Packet: Provê informações para ligar um pacote a uma lista (PacketQueue, por exemplo); Faz referência a uma área de armazenamento contendo os cabeçalhos do pacote (por protocolo); Faz referência a uma área de armazenamento contendo dados do pacote. Formato De Pacotes (Cont.) cmn header header data ip header tcp header rtp header trace header ... ts_ ptype_ uid_ size_ iface_ Cabeçalhos A estrutura hdr_cmn é o cabeçalho “comum” a todos os pacotes. Principais campos: ts_ -> instante em que o pacote foi criado. ptype_ -> identifica o tipo do pacote. uid_ -> identificador único de cada pacote. size_ -> tamanho simulado do pacote em bytes. iface_ -> identifica em qual link o pacote foi recebido. Cabeçalhos (Cont.) É comum que cada protocolo implemente o seu próprio cabeçalho. Exemplo: Arquivo .h struct hdr_rtp { u_int32_t srcid_; int seqno_; u_int32_t& srcid() { return (srcid_); } int& seqno() { return (seqno_); } /* Packet header access functions */ static int offset_; inline static int& offset() { return offset_; } inline static hdr_rtp* access(const Packet* p) { return (hdr_rtp*) p->access(offset_);} } Cabeçalhos (Cont.) Arquivo .cc static class RTPHeaderClass : public PacketHeaderClass { public: RTPHeaderClass() : PacketHeaderClass("PacketHeader/RTP", sizeof(hdr_rtp)) { bind_offset(&hdr_rtp::offset_); } } class_rtphdr; A estrutura hdr_rtp define o layout do cabeçalho. Usada pelo compilador apenas para definir o tamanho em bytes do cabeçalho (offset). A variável offset_ é usada para encontrar a posição do cabeçalho rtp na área de memória em que o pacote é armazenado. Como Criar Um Novo Cabeçalho Criar a estrutura do cabeçalho Permitir tracing do novo cabeçalho (packet.h) enum packet_t { PT_TCP, …, PT_MESSAGE, PT_NTYPE // This MUST be the LAST one }; class p_info { …… name_[PT_MESSAGE] = “message”; name_[PT_NTYPE]= "undefined"; …… }; Como Criar Um Novo Cabeçalho (Cont.) Criar classe estática para OTcl linkage Registrar o novo cabeçalho em OTcl (tcl/lib/nspacket.tcl) foreach prot { { Common off_cmn_ } … { Message off_msg_ } } add-packet-header $prot Estes passos não se aplicam quando adicionamos um novo campo a um cabeçalho existente! Como Funciona O Cabeçalho Packet PacketHeader/Common next_ hdrlen_ bits_ size determined at simulator startup time (PacketHeaderManager) size determined hdr_cmn at compile time PacketHeader/IP size determined at compile time size determined at compile time …… hdr_ip PacketHeader/TCP hdr_tcp Gerenciamento De Filas head_ Filas são locais de armazenamento onde pacotes são contidos (ou descartados). No ns, filas fazem parte dos enlaces entre nodos. enqT_ tracing queue_ drophead_ deqT_ drpT_ link_ ttl_ simplex link Uso: ns_ duplex-link $n0 $n1 5Mb 2ms DropTail Node entry Gerenciamento De Filas (Cont.) A classe Queue implementa as funcionalidades básicas de uma fila. Principais métodos: void enque(Packet*) Packet* deque() void block() void unblock() Implementados pelas classes herdeiras. Os métodos block() e unblock() são utilizados para bloquear e desbloquear a fila. Este mecanismo é utilizado para simular atraso de transmissão. Gerenciamento De Filas (Cont.) O ns disponibiliza diferentes tipos de fila: DropTail; Fair Queueing (FQ), Stochastic Fair Queueing (SFQ) e Deficit Round Robin (DRR); Gerenciamento de buffer RED; Class-Based Queueing (CBQ) e CBQ/WRR (Weighted RoundRobin). Gerenciamento De Filas (Cont.) Objetos QueueMonitor são usados para monitorar um conjunto de informações como chegada e partida de pacotes e contadores de descartes em filas, além de gerar estatísticas como tamanho médio de fila. Uso: $ns monitor-queue $n0 $n1 <trace> <intervalo> O ns permite criar um trace específico de uma fila pertencente a um enlace através do comando: $ns trace-queue $n0 $n1 <trace> Agentes Agentes são endpoints onde pacotes são construídos e consumidos. São usados na implementação de protocolos em várias camadas: Protocolos da camada de transporte, por exemplo UDP e variações do TCP. Protocolos de roteamento, por exemplo Distance-Vector. Agentes (Cont.) Vários agentes são disponibilizados pelo ns. Os mais conhecidos são: TCP e suas variações (Vega, Reno, Newreno...); TCPSink, um receptor TCP Reno ou Tahoe; UDP LossMonitor, um receptor de pacotes que produz estatísticas de perda de pacotes; Null, um agente que descarta pacotes; rtProto/DV, que simula o protocolo de roteamento distancevector. Agentes (Cont.) Agentes são modelados pela classe Agent, implementada em C++ e OTcl (~ns/agent{.h,.cc} e ~ns/tcl/lib/ns-agent.tcl}). Apresenta algumas variáveis utilizadas para inicializar campos dos pacotes criados: addr_ -> endereço do nodo ao qual o agente está conectado; dst_ -> endereço do nodo destino; size_ -> tamanho do pacote gerado em bytes; type_ -> tipo do pacote gerado. Agentes (Cont.) A classe Agent provê métodos para geração e recebimento de pacotes: Packet* allocpkt() -> aloca um novo pacote e inicializa seus campos. Packet* allocpkt(int n) -> aloca um novo pacote com um tamanho n de dados. void recv(Packet*, Handler*) -> primeiro método invocado quando um pacote é recebido. Agentes (Cont.) n0 n1 Port Classifier Port Classifier Addr Classifier entry_ 0 1 0 dmux_ dst_=1.0 Addr Classifier Agent/TCP agents_ Link n0-n1 entry_ classifier_ 1 0 classifier_ Link n1-n0 0 dmux_ dst_=0.0 Agent/TCPSink agents_ Utilizando Agentes Cria-se agente emissor e o conecta ao nodo fonte: set tcpSource [new Agent/TCP] $ns attach-agent $n0 $tcpSource Cria-se agente receptor e o conecta ao nodo sorvedouro: set tcpSink [new Agent/TCPSink] $ns attach-agent $n1 $tcpSink Conectam-se os agentes emissor e receptor: $ns connect $tcpSource $tcpSink Criando Um Novo Agente Cria-se o cabeçalho do novo protocolo (conforme instruções anteriores). Cria-se uma classe em C++ que estende a classe Agent. Arquivo .h class MeuAgente : public Agent { public: MeuAgente(); int command(int argc, const char*const* argv); void recv(Packet*, Handler*); }; Criando Um Novo Agente (Cont.) Arquivo .cc MeuAgente::MeuAgente() : Agent(PT_MEUAGENTE) { bind("packetSize_", &size_); } int MeuAgente::command(int argc, const char*const* argv) { ... } void MeuAgente::recv(Packet* pkt, Handler*) { ... } Criando Um Novo Agente (Cont.) Cria-se classe estática para OTcl linkage Arquivo .cc static class MeuAgenteClass : public TclClass { public: MeuAgenteClass() : TclClass("Agent/MeuAgente") {} TclObject* create(int, const char*const*) { return (new MeuAgente()); } } class_meuagente; Criando Um Novo Agente (Cont.) Inserir valores default para as variáveis do agente. Arquivo ~ns/tcl/lib/ns-default.tcl Agente/MeuAgente set packetSize_ 64 Adicionar o arquivo .o gerado na lista de arquivos objeto do ns no arquivo Makefile.in e executar ./configure. sessionhelper.o delaymodel.o srm-ssm.o \ srm-topo.o \ ping.o \ $(LIB_DIR)int.Vec.o $(LIB_DIR)int.RVec.o Aplicações Aplicações são construídas no topo dos protocolos de transporte. Modeladas através da classe Application. Principais métodos: void void void void send(int nbytes) recv(int nbytes) start() Implementados pelas classes herdeiras. stop() Aplicações (Cont.) Utilizam os serviços dos protocolos de transporte através de chamadas para os seguintes métodos: send(int nbytes) sendmsg(int nbytes, const char* flags = 0) close() listen() Aplicações (Cont.) n0 n1 Application/FTP dst_=1.0 Port Classifier Addr Classifier 0 entry_ 0 Port Classifier Agent/TCP agents_ dmux_ Addr Classifier 0 1 dmux_ entry_ classifier_ classifier_ dst_=0.0 Agent/TCPSink agents_ Geradores De Tráfego Tráfego é gerado em intervalos, que podem seguir uma determinada distribuição ou não. Geradores de tráfego disponíveis: Exponencial -> geram tráfego de acordo com uma distribuição Exponencial On/Off Pareto -> geram tráfego de acordo com uma distribuição Pareto On/Off CBR (Constant Bit Rate) -> geram tráfego a uma taxa constante Geradores De Tráfego (Cont.) Uso: set src [new Agent/UDP] set sink [new Agent/UDP] $ns_ attach-agent $n0 $src $ns_ attach-agent $n1 $sink $ns_ connect $src $sink set e [new Application/Traffic/Exponential] $e attach-agent $src $e set packetSize_ 210 $e set burst_time_ 500ms $e set idle_time_ 500ms $e set rate_ 100k Geradores De Tráfego: Trace Driven ns permite geração de tráfego a partir de arquivos de trace. Uso: set tfile [new Tracefile] $tfile filename <file> set src [new Application/Traffic/Trace] $src attach-tracefile $tfile <file>: - Formato binário - inter-packet time (msec) e packet size (byte) Aplicações Simuladas ns permite a simulação de dois tipos de aplicações: Application/FTP Application/Telnet Aplicações Simuladas (Cont.) Uso set tcp1 [new Agent/TCP] $ns_ attach-agent $n0 $tcp1 set sink1 [new Agent/TCPSink] $ns_ attach-agent $n1 $sink1 $ns_ connect $tcp1 $sink1 set ftp1 [new Application/FTP] $ftp1 attach-agent $agent Encaminhando Pacotes n0 n1 Port Classifier Addr Classifier entry_ 0 1 0 Application/FTP dst_=1.0 Port Classifier Addr Classifier Agent/TCP Link n0-n1 entry_ Link n1-n0 1 0 0 dst_=0.0 Agent/TCPSink