Vamos agora olhar um código, na verdade, códigos em C, C mais mais. Nós estamos dando esse curso aqui de redes de computadores de uma forma muito abstrata, porque se fôssemos olhar isso aqui a fundo mesmo, estaríamos debulhando código em C. Recomendo que vocês estudem C mais mais para compreender como funcionam as redes de computadores e os sistemas operacionais. Vocês vão encontrar, saber as limitações, vocês vão entender da onde vem as vulnerabilidades, muitas, desculpe, das não, muitas das vulnerabilidades que encontramos. É proveniente inclusive de falhas da linguagem. As linguagens são falhas também, gente. Bom, aqui o tannibal, eu não sei o que ele quis fazer. Eu estou a minha palavra que eu não sei o que ele quis fazer. Porque geralmente o tannibal coloca em um círculo ou uma elipse os programas, os programas de computadores, programas que nós programamos. E aí, naturalmente, eu não sei se ele quis colocar aplicação dentro de um elipse para dizer que é um programa de computador ou se ele está falando da camada de aplicação, que deveria ser quadradinha. Entendeu? Você está entendendo o que eu estou te falando, ele não sei o que ele quis fazer. Mas eu vou explicar. Nós programamos nossos sistemas, nossos programas e nós não precisamos reconstruir toda a rede de computadores. Foi mal, eu dei um corte aqui na minha tosse. Agora eu tenho um botão de damute. Então o que acontece? Nós podemos construir nossos programas sem precisar de reconstruir toda a tecnologia das redes de computadores. Então, nós precisamos utilizar o que já tem. E aí nós temos uma camada que nós não, na verdade, eu não lhes expliquei ainda, chamada camada de aplicação. E o nosso programa que a gente faz, o nosso programinha, está em cima da camada de aplicação. Então quem? Que no modelo TCP estaria em cima da camada de transporte, que estaria em cima da camada de rede, que estaria em cima da camada de enlace. E é isso que eu te falei. Eu não sei o que ele quis dizer com aplicação. Eu não sei o que ele quis dizer, aplicação do sistema opressional, aplicação do kernel, aplicação como camada. Legal. E aí nós temos preste atenção. Isso é que é muito, cara, pô, na verdade, poucos são os pontos do livro do Tanebel, que vai definir a fronteira da realidade do mundo físico, tá? Como mundo virtual, no caso, o mundo lógico, tá? Ele fica ali na interface de rede, cara. Tá? A camada de enlace, ela é subdividida em duas subcamadas. Já falei. Subcamada MAC, que está mais embaixo, e está na interface de rede. NIC, NIC é interface de rede. Tá? E, naturalmente, o driver que está ali na LLC, na subcamada LLC, ali é a fronteira entre o mundo físico real e o mundo lógico do sistema opressional. Oh, rimou, hein? Tá? E essa imagem, ela representa isso perfeitamente, tá? Então sua placa de rede tem toda a camada física e parte da camada de enlace no modelo OZ. Por isso que no modelo, presta atenção, por isso que no modelo TCP, a camada física e a camada de enlace é a mesma camada, tá? Então no modelo baseado no modelo OZ, da ISO, física e enlace são duas camadas diferenciadas. Na prática do mundo real que nós vivemos, aplicado na prática, nós temos, então, a camada física e enlace como uma única camada, tá? Faria mais sentido, né? Afinal, ponta, que pariu. Ah, ela viu a minha cachorra. É de estoura, fogos, aí minha cachorra fica doidona aqui. Ah, e que que acontece? Isso faz mais sentido, tá? Então, legal, né? Vamos ver aqui um código, type, numa definição de type chamado enum, chamado boleano, tá? Então, o dedo tem o valor false true. Por que não existe o boleano? Nós temos em C, 0 e 1. Inclusive, quando nós testamos, fazemos o I ou fazemos for, ou fazemos o if, que são as estruturas de desvio condicional de fluxo baseado em testes. Nós usamos 0 e 1, porra. A gente usa true, false. A não ser que você construa a enumeração. Aí você constrói a enumeração e usa a enumeração. Aí tudo bem, tá? Aí tudo bem. Ele criou ali o ansignet, significa só números positivos. Caste 0 pra cima, tá? Aí ele tá criando uma estrutura, tá? Uma struct. Geralmente, nós fazemos as structs pra ler coisas. Bom, vamos lá. Você é programador Java, né? Você é programador C-Sharp, né? Você sabe que quando você tem algo e você quer tipar ele, você utiliza um cast. Aí você vai lá, põe um cast. Então, eu tenho o object. Eu sei que esse object é do tipo cliente. Aí eu uso um cast cliente com esse object. É assim que você faz quando você programa em linguagem de altíssimo nível. Então, aqui a gente usa esses structs pra ver, ler e tipar algo, tá? E esse algo tem os tipos primitivos. Um número ansignal, char, tem data, tá? Então você vai criando aqui os tipos, tá? Tem o tipo frame também, tá? Legal. Aqui eu estou tipo assim, utilizando essas assinaturas, que a gente chama assinatura de método ou função. Se você programar em alto nível, orientar do objeto, você vai falar assinatura de método. Aqui é assinatura da função. Então existe uma função chamada wait for event, tá? Que aceita um event type. Se você olhar, tem um event type definido aonde? Cadê ele? Tem ali o boleano. Não tá aí, não tá definido ali não, tá? Um event type. Provavelmente já tá na biblioteca já. From Network Layer, que vai receber o pacote. Você define todos por um motivo muito simples. Não sei se vocês sabem em C. Se você não faz a definição das assinaturas dos métodos, você tem que colocar o void main lá no final, que o void main chama a função de cima. Então você tem que ordenar as funções da seguinte forma. Aquela que chama outra função vai embaixo. E é um inferno fazer esse tipo de organização, tá? Eu mesmo gosto. Então eu coloco as assinaturas dos métodos das funções, desculpe, coloca as assinaturas das funções tudinho, tá? Não precisa de uma sequência. E aí depois eu coloco os métodos na sequência que eu quero, ou no caso as funções aqui, na sequência que eu quero, tá? Então tem essa chatice, tá? E todo mundo faz essas definições, tá? Porque é muito chato você colocar o void main atrás, porque ele chama uma função, aí essa função tem que estar acima do void main, e aí essa outra função chama outra função, que essa outra tem que estar acima dessa função. E aí começa a confusão, tá? Da estruturação do teu código em C. Tá? Eu acho isso ruim. Legal. E isso aqui ele criou, isso aqui é o tal do protocol.h, tá? Na programação em C nós poderíamos socar tudo num arquivo. Foda-se, meu linhas. Só que isso vira um inferno. Por isso que nós construímos um arquivo chamado AlgumaCosa.h, AlgumaCosa.h de header, e definimos as coisas lá, que a gente define lá. E depois nós vamos no nosso arquivo.c, tá? Que chamamos esse protocol.h, tá? Isso aqui é uma forma de você, né? Tem um código mais limpo, mais chuto, menos redundante, modularizado. Não sei se vocês viram no curso de vocês de programação básico, você tem lá, né? Um trabalho de modularização do teu código, tá? E reestruturação, tá? É não sei porque eu aprendi a programar em uma época que a oratação-objeto não era usado com tanta frequência, tá? Eu aprendi na década de 90. E os cursos de programar, embora a senhorita subjetos, eu sei o que você vai falar, mas as faculdades brasileiras não estavam prontas. As universidades não estavam prontas. A minha universidade não estava pronta. Meus professores eram dinossauros. Então imagina, né? E ali, então, nós tínhamos muito ensinamento de como fazer códigos estruturados, né? Bem... Então era assim que a gente aprendia, tá? Então nós tínhamos modularização do código, tá? FrameS, ou seja, S é do tipo da struct frame. E buffer é um tipo pacote que tá definido lá no protocol.redder, aqui onde nós temos a definição do type def struct, tá? Frame, beleza? Fechou. Então vamos lá. O Iotru, porque ele criou uma enumeração, tá? Se eu não quisesse ter criado a enumeração, eu teria colocado um. O Iotru, porque ele criou uma enumeração, tá? Lógico, abre e fecha o parênteses, né? A chave tá estilo Java, né? Depois do I.O, né? Geralmente, no programa em C, eu esperaria essa chave abaixo do I.O. Não impacta em nada, mas é o esperado, né? Pra quem programa em C, né? Mas talvez o autor quis fazer assim pra reduzir o número de linhas, porque afinal ele vai pôr isso aí no slide, no livro, né? Isso é importante. Então, from network layer, eu passo o endereço do pacote. Sabemos que estamos na camada de inlass, camada 2. Esse código é da camada 2. E ele tá passando para a camada 3, o endereço do pacote, pra ser naturalmente preenchido. Bom, nesse momento, você tem que saber que o from network layer pode não ter dados. Ou seja, from network layer é uma chamada bloqueante. Lembra de sistemas operacionais modernos que vocês tinham pronta, executando e bloqueado os estados de um processo, capítulo de processo, tá? Volta lá no livro e estuda essa parte. O processo vai ser bloqueado até que a camada 3, a camada network, tenha dados no pacote, vai preencher lá. Digamos que o pacote foi preenchido e foi liberado o processo. O processo saiu de bloqueado e foi pronto pra ser executado. Quando ele chegar em execução, naturalmente, ele vai pegar o pacote e jogar dentro do campo info do quadro. Por quê? Na camada 3, network, você tem pacote. Na camada 2, em lá, você tem o quadro. Vimos no começo, alguns vídeos atrás, do começo desse capítulo, que o quadro tem uma área chamada Playload Field, aqui eles o Info, tá? O programador o quis assim, em que o quadro, ele recebe dentro desse Playload Info o pacote. E aí eu coloco para camada física, eu mando o endereço do quadro, que vai ser transformado em bits e enviado. E vai. Também é bloqueante, tá? Também é bloqueante. Essa thread vai ficar bloqueada, tá? Há um evento type, ele definiu aqui, ou talvez eu cortei errado, tá? Essa linha aqui deveria ter aqui o corte errado, cara. Não, o livro que cortou errado, olha lá, olha aqui, o livro cortou errado, cara, olha a merda aqui, o livro que cortou errado, isso aqui deveria estar aqui. E aí depois tinha o fechamento da descrição aqui, que cagada, mano. Você viu? A gente roda o livro do Thunderbolt e vai achando cagada. A gente roda o livro do Thunderbolt e achando cagada. Aqui eu também tenho o frame, aqui eu também tenho type event. E um item true. O 8-4 event, então eu estou aguardando por um evento, tá? Esse aguardar um evento ele é uma chamada bloqueante. Ele vai estar em execução, ele vai para bloqueado, se não tiver nada. Quando chega alguma coisa na placa de rede, tipo assim, alguma coisa chegou na placa de rede. O que vai acontecer? Vai ser enviado um sinal de interrupção, tá? A interrupção vai parar tudo, vai parar o CD-ROM, o CD-ROM vai continuar girando, né? Vai parar a leitura do CD-ROM, vai parar a leitura do seu HD, vai parar a escrita da memória, vai parar tudo, vai parar os barramentos, para tudo, congela. Isso é uma interrupção. Salva tudo que está no buffer nos registradores. O professor, o que é buffer e registrador? Qual a diferença? AOC. Estuda AOC que você vai saber. Ok? Estuda AOC que você vai saber. Se você estuar o C você vai saber. Vai jogar os registradores dos buffers, vai carregar todos os dados do Schedule, o Schedule vai olhar a natureza da interrupção, ele vai falar, puta merda, é uma interrupção de placa de rede para o processo que vai receber, que é esse código que você está vendo aqui, ou para a Tread que vai receber. Ok? Aí, o que o Schedule faz? Ele coloca aqui, anotado em algum lugar, o próximo processo que vai sair de bloqueado e vai vir para a execução, é o nosso amigo simplexer restrição. Tá? Aí, o que vai acontecer? Tudo que estava nos registradores do Schedule, vai ser salvo nos buffers, vai parar toda a máquina, tudo para, vai ser feito isso, vai ser naturalmente desbloqueado o processo de leitura de placa de rede, vai ser feito, colocado em execução e vai ligar tudo de novo. Isso é chamado de interrupção, cara. Sempre que é bloqueante, é assim, cara. Tá? E ele vai fazer esse tipo de interrupção, cara. É bloquear tudo. Tá? Isso aqui é um transtorno, tá? Só para vocês terem a noção, uma vez eu estava numa empresa aí e aí me chamaram por causa de vírus, de malware. Aí, então, o malware aqui tá fudendo a gente. Aí eu olhei, cara, todas as máquinas, se ele gava, eles mostraram. Na verdade, ele tinha detectado isso. Ligava a máquina, cara, todo qualquer máquina. Cara, ligava a máquina, processamento, subia algo em todo de 14%. Cara, com a máquina ligada, 14% sem nada. Toda máquina. Tudo bem que era bosta do Windows. Vamos lá. Sabe o que era? A bosta de um loop de rede para o endereço de broadcast, fudendo toda rede e fazendo esses desbloqueios excessivamente, cara. Tá? Cara, se chegou essa interrupção até aqui, nesse código, é porque essa conexão era para essa máquina. Tá? Era para essa máquina. Então, já foi passada pelo filtro do Mac address, pela camada Mac. Subcamada Mac, desculpe, da camada de endereço. Já foi filtrado, mas não, passou. Então, esse esquema de interrupção excessivo numa rede leva a bloqueios excessivos da auto-sensuracional, a interrupção excessiva que leva ao processamento excessivo, porra, de toda infraestrutura. Sabe o que era? Um router de plástico. Um switch de plástico. Aquelas porcarias de plástico. Cara, nesse dia eu peguei um ódio de switch de plástico, de router de plástico, sério, cara, eu peguei ódio. Ódio. Então, ele fica guardando. Wait for event, fica guardando, fica guardando, fica guardando, fica guardando. Pum! Liberou todo esse negócio que eu te falei, liberou o processo, ele manda endereço para a camada física, preenche os dados, pega o campo info do quadro e manda então para a camada de rede acima, tá? Repare que ele não está fazendo nenhuma tratativa de correcção de erro, essa camada de enlace, esse código, está só pegando da camada física e mandando para a camada de rede. Pegando da camada de rede e mandando para a camada física, só isso. Só isso. Eu não tenho um tipo de tratativa de verificação de erro, de tamanho de quadro, de checksam, nada. Então, aqui estaria dentro aqui o código de validação. Então, aqui no meu enviar, aqui estaria criando o código de validação de erro, colocando aqui e no receber, estaria obtendo a camada física. Aqui, ó, deveria ter todo um código que pegaria. E o checksam validaria se isso aqui é válido ou não e mandaria para a camada de rede somente se tivéssemos sucesso, tá? Então, é um código, por isso que ele é chamado Simplex sem nenhum tipo de restrição, tá? Esse código se chama Simplex sem nenhum tipo de restrição. Eu vou mostrar para vocês agora uma alteração do código para um momento em que eu mando, aguardo, confirmação. Mando e aguardo, confirmação. Isso aqui, voltando a esse código antigo, seria código de transmissão de erros, tá? Código de transmissão de dados sem feedback. Aqui é com feedback. Vamos ver a mudança, então, de selecionar aqui um feedback. Tá? Ok? Então, vamos lá. Frame, pacote, event type. Legal. I'll true, como sempre, tá? From network layer da camada 3, eu passo o endereço, pego o quadro, jogo no Playload Info, do quadro, pego o pacote, jogo no Playload Info do quadro. Legal. E aí eu passo para a camada física, o meu quadro. E aí eu don't wait for event. Como assim? Eu bloquei o processo. O processo estava em execução. Eu mando ele para fila de bloqueados. Para fila de bloqueados. E aí os dados estão indo pela rede. Chega lá do outro lado. No I'll true, wait for event, chega lá do outro lado. Aí ele vai from, physical layer, pega o quadro, manda para a camada de rede, o campo Playload Info, tá? E manda para a camada física o quadro de volta, para retornar ao quadro. Ou seja, esse cara estava bloqueado no wait for event. De repente, chega uma interrupção, a toda aquela tratativa de, a toda aquela tratativa do schedule, tudinho, do sistema profissional, desbloqueia o processo e aí volta para mandar a próxima. Ou seja, ele só desbloqueia se chegar uma resposta, se chegar um feedback. Por isso que quem recebe, manda de volta. Olha a diferença de quem recebe do anterior. Ele simplesmente recebe e manda para a camada de rede e não manda nada de volta para outra máquina. Não manda o feedback, é que ele mandou feedback. Bom, novamente, nesse feedback, no quadro, ele poderia colocar taxa de processamento, taxa de transmissão, o cálculo de tempo de enfileiramento. Ele poderia retornar aqui, naturalmente, n informações e aqui desse lado, quando ele receber, ler o quadro de volta aqui, aqui embaixo, e poder essas informações como está o outro lado, para poder regular seu próprio fluxo. Tá? Taria aqui o código. Veja como é bom programar. E quando você programa e você tem que aprender a programar, porque você entende o funcionamento dos sistemas opressionais, você entende o funcionamento das redes de computadores, você não precisa de ver o código. Porra, se você tem alguma validação de feedback, tá aí aqui, porra. Taria aqui, onde está aqui. Se você tem alguma coisa gerando dados, para que o outro lado saiba como eu estou, estaria aqui, aqui, porque você já sabe programar. Você saberia onde estaria as coisas, vamos dizer assim. E da mesma forma que você consegue bolar, pegar a teoria e pensar como seria o código, você, quando usa um programa de computador, você sabe como é que é o código, sem precisar de ver o código fonte. Eu sei onde está as possibilidades de erro, eu sei onde está a possibilidade de sucesso. Então, pense assim. Aqui é um código um pouco mais complexo. Aqui ele está fazendo tratamento de ruído, ou seja, erro, validação de erro em geral. Então, está aqui. Acorte, evento, buffer, e aí ele está criando um Todd Next Frame, que vai ser enviado. Contador zero. Forn network layer, o iotru, e aí repare que ele manda para a placa de rede, repare que aqui ele estava onde. O forn network layer estava dentro do laço de repetição. Aqui o forn network layer está fora, porque ele vai repetir, imagina que tivesse um forn, um laço iotru, chamando o sender3. Então teria um laço de repetição aqui em cima, chamando isso tudo aqui. Chamando isso tudo aqui. Network layer, é, isso, network layer, o pacote, aí colocaria aqui dentro o quadro, o número de sequência, repare que ele está adicionando o número de sequência. Tá? Aqui, ó, ele está adicionando o número de sequência, que é zero, tá? Aí ele manda para a camada física e aguarda um tempo. Aqui ele vai iniciar um relógio virtual, aonde que eu vejo a teoria de relógios virtuais. Também no livro do Thunderbolt, relógio virtual, que temos operacionais modernos no capítulo de dispositivo de entrada e saída. Tá? Tá mais ou menos no meio do livro. Ah, cara, porra, como é importante saber ler os livros do Thunderbolt? Tá? Porra, qual é o impacto disso? Entendiu por que um relógio virtual teria tanto destaque assim em uma aula. Porra, um relógio virtual é um cronômetro, imagina você ser um cronômetro invertido, tá? Tá? Vamos imaginar aqui de 7 segundos. E ele começa, reduzido, vem reduzido, 6, 5, 4, 3, 2, 1, chega a zero, sabe o que ele faz? Mete uma interrupção. O que eu falei sobre interrupção? Para tudo. Chama o esquadro. O esquadro decide o que vai ser feito. Para tudo de novo. Por um tratador entrar em execução. Cara, é muita coisa, cara. Então, quando eu falo, quando você vai abrir um relógio virtual no sistema operacional, você tá ferrando. Existe um, um, como eu posso dizer, existe ali uma guerra de ideias. É melhor um laço, o IOTRU bloqueando, bloqueando, insulto de processamento alto, ou trabalhar com interrupção? Bloqueante ou interrupção? O que eu faço? Existe, inclusive, nas redes de computadores, né? Essa, esse dilema, qual dos dois eu utilizo? Por favor, leia com atenção o livro do Tânibão de sistemas operacionais bodetos. Então, ele abrir um relógio virtual, cara, isso não é muito bom, não? Pô. E aí, ele vai aguardar o evento. Se não chegar o evento em 7 segundos, vai estourar a função. Como assim estourar? Vai dar uma saída aqui, ó. Ele vai dar um par, um break. Vai dar um break na função, cara. Não vai rodar. Vai levar um exception, tratativo e tudo mais. Sério mesmo. A EEP é de código. Provavelmente tem um Aiotrú, que nunca recebeu a resposta, não viu o final de sucesso. O Aiotrú reenvia o pacote novamente. Tá? A evento, agora, digamos que eu recebi um evento. Tá? Eu recebi um evento de placa de rede. Se o evento é do tipo, então, lá da chegada, eu pego da camada física e analiso-se o acnôler de no outro lado, bate com o meu frame de sequência. Se é o meu frame de sequência que veio do acnôler de feedback, eu paro o relógio virtual antes que ele estore, e aí, naturalmente, eu pundo para a camada de rede e incremento o meu número, que seria de zero e iria para um. Por que que você usou uma função para incrementar o número? Por que que você não veteu mais, mais? Cara, você não leu o livro do Tano, ou se não lheu para as operações modernas? Não, porra! Eu tenho um problema chamado região crítica. E sabe onde está a região crítica desse código? No incremento desse número. De sequência. Estou sacanhando? Não, porra. O número de sequência, um simples cálculo de... ou um número mais um número, são várias operações de máquina. E o quantum de processamento pode parar no meio do incremento. E se eu tenho, threads disputando, fudeu! Eu posso ter o reenvio, por exemplo, de pacotes diferentes com o mesmo número de sequência? Não pode. Então, quando eu entro em incremento, ele cria um mútex no sistema. Esse incremento não está aqui, tá? Essa função de incremento. Ela cria um mútex no sistema que, mesmo que termine o meu quantum de execução, eu não saio do processamento. Eu continuo até conseguir fazer aquela função e terminar a minha região crítica. Mútex. Porra, cara, você tem que ler o livro do Tano e postarmos operações modernas, tá? Porra, não era um código idiota? Tá virando uma aula de sermos operacionais? É isso aí. É assim mesmo. Quando você programa, você pensa no sistema operacional. O programador que não pensa no sistema operacional, ele está cagando para o negócio. Ele só quer o quê? Tem um quadro de requisito funcional. Eu tenho um monte de post-it, aqui é post-it na minha mão, tá? Eu tenho um monte de post-it pregado no cambã. Foda-se, eu quero que os post-it vai para lá. Eu fiz, eu fiz, eu fiz. Testei, porcamente. Fui, vai para lá, post-it. E isso não é um programador, não, tá? É um digitador de código. Então, vamos lá. O IOTRU, o 8.4, é evento bloqueado ali, né? Bloqueado. Chego o evento da placa de rede. Então, eu analiso se o evento é um tipo de chegada e aí eu vou para a camada física, pego o frame, eu pego o quadro, né? É o frame, né? No livro em inglês. Olhe o número de sequência. É o que eu espero que chegue. E aí eu mando para a camada de network e eu incremento o que eu espero que seja o próximo. Ok? E aí eu pego um AAC-nolot. Por que que eu pude fazer operação aqui assim? Eu poderia ter pego isso aqui, ter colocado aqui em cima. Por que que ele incrementa? Ah, não, não tá certo, tem que ser assim mesmo. Tem que ser assim mesmo. Tá certíssimo. Tem que ser depois mesmo, tá? Porque pode não ser, então ele volta. Pode ter sido um erro, não é o esperado, ele volta. Aqui eu faço um cálculo, tá? De um menos o que é esperado. E aí ele sabe quantos para trás você erra. Tem até uma imagem para isso. Mas para frente eu vou mostrar essa imagem. E aí ele manda para a camada física, tá? Aqui eu não precisei de fazer o tipo igual aqui o incremento. Por que? Ele não é uma região crítica. Agora, aqui é um cálculo de região crítica, tá? Aqui eu tenho que executar o cálculo todo para o processo sair, caso quanto do tempo seja no meio da incremento. Cara, vocês estão impressionando uma coisa meio fodinha, cara. É fodinha. Próximo vídeo. Vou falar sobre o protocolo de janela deslizante. Tá? Eu vou explicar porque que é janela e porque que é esse negócio de desliza, pô. Até mais, até o nosso próximo vídeo. Tchau.