FSC Tema3 Recortado

29
Fundamentos de Software de Comunicaciones Tema 3 Fundamentos de Fundamentos de diseño de capas de protocolos (1ª parte)

description

software

Transcript of FSC Tema3 Recortado

Page 1: FSC Tema3 Recortado

Fundamentos de Software de Comunicaciones

Tema 3

Fundamentos de Fundamentos de diseño de capas de protocolos (1ª parte)

Page 2: FSC Tema3 Recortado

Elementos de diseño e implementación

� Flujo de datos entre capas

2

Page 3: FSC Tema3 Recortado

Elementos de diseño e implementación

� El mecanismo de funcionamiento de cada protocolo normalmente se encuentra descrito en un estándar (ITU, ETSI, RFC, IEEE)

� Aspectos de implementación de capas:

o Clasificación en función del procesado que realiza el protocolo:

• procesado de datos (trabajo sobre payload, por ejemplo • procesado de datos (trabajo sobre payload, por ejemplo segmentación, reensamblado)

• procesado de control (de la cabecera y de la evolución del estado del protocolo en función del PCI)

• funciones de soporte: procesado de buffers y gestión de temporizadores

3

Page 4: FSC Tema3 Recortado

Comunicación entre capas (I) PRIMITIVAS OSI/3GPP

� Modelo de comunicación que garantiza la independencia espacial entre capaso No hace suposiciones sobre dónde se ejecuta

cada capa (distintos procesos, nodos...)

N

N-1

N

N-1

REQUEST CONFIRM INDICATION RESPONSE

12

Page 5: FSC Tema3 Recortado

Diseño e implementación de arquitecturas de protocolos

� A pesar de los estándares de protocolos, hay muchas cuestiones de diseño e implementación que se dejan a los programadores

� Por ejemplo: ¿cómo implemento cada capa? ¿En � Por ejemplo: ¿cómo implemento cada capa? ¿En software? ¿En hardware dedicado?

14

Page 6: FSC Tema3 Recortado

Capas en software

� Mapeo 1-a-1o Cada capa es una unidad funcional (por ejemplo

un proceso)

Necesidades: colas de mensajes y distinción demensajes que van en sentido "downlink" o "uplink"

Atender a un mensaje se realiza de forma asíncrona:la capa que envía el mensaje sigue su ejecución, lacapa que lo recibe, lo atiende cuando lo desencola.Algoritmo:

while(1){espera_evento(&evento);procesa_evento(evento);

}

15

Page 7: FSC Tema3 Recortado

Gestión de mensajes entre capas

� El mismo buffer se utiliza para guardar todas las cabeceras y payload

� El tamaño máximo del buffer es el MTU de la red

� Ejemplo de uso para PDUs en sentido descendente:

19

Page 8: FSC Tema3 Recortado

Gestión de mensajes entre capas (II)

char * pduN

char * pduN_1

char * pduN_2

20

Page 9: FSC Tema3 Recortado

Elementos de soporte

gestor detemporizadores

BUFFERCIRCULAR

ZONA DE DMA

NIC

Inserta trama ygenera interrrupción

Atiende a la interrupción y crea un buffer donde copia la trama

22

Page 10: FSC Tema3 Recortado

Diseño e implementación de la parte de control

� Se utilizan máquinas de estados finitoso Se implementa un autómata que decide las funciones a

realizar en el protocolo, a partir de

• el estado actual del autómata

• la información de control del protocolo recibida en un paquete

• el resultado de procesar los datos

o Se pasa de un estado a otro cuando se reciben eventoso Se pasa de un estado a otro cuando se reciben eventos

• llegada de paquetes o eventos de tiempo (timeouts)

o Se verán varias técnicas de implementación de una máquina de estados:

• basada en código (con dos bucles anidados IF o SWITCH/CASE)

• basada en tablas (array dos dimensiones: [estado][evento])

7

Page 11: FSC Tema3 Recortado

Protocolos y máquinas de estados� Cuando un protocolo tiene estado, se necesita implementar

su comportamiento mediante una máquina de estados

� En programación imperativa existen dos aproximaciones:1. Lineal: a través de sentencias anidadas

• switch(estado)/case { switch(evento)/case}• rápido, poco modular

2. Tabla de punteros a función manejadora• protocolo[estado][evento](argumentos)• costoso en memoria, pero modular30

Page 12: FSC Tema3 Recortado

Máquinas de estado (I)� Implementación con doble anidamiento

const int estadoA = 0; const int estadoB = 1;const int evento0 = 0; const int evento1 = 1;

int estado = estadoA; /*estado inicial*/bool fin=false;while(!fin){

int evento;espera_evento(&evento); /*bloquea*/switch(estado){

case estadoA: switch(evento){

case evento0: cout << "conmutaA->B\n";cout << "conmutaA->B\n";estado = estadoB;break;

case evento1:cout << "fin\n";fin=true;break;

}break;

case estadoB:switch(evento){

case evento0: cout << "fin\n";fin=true;break;

case evento1:cout << "conmutaB->A\n";estado = estadoA;break;

}break;

default: cerr << "Estado no esperado\n"; fin=true; break;}

}31

Page 13: FSC Tema3 Recortado

Máquinas de estado (II)

� Implementación con tabla de punteros a funciones

const int estadoA = 0; const int estadoB = 1;const int evento0 = 0; const int evento1 = 1;

int estado = estadoA; /*estado inicial ¡es global!*/

int transita_A_B(){cout << "conmutaA->B\n";estado = estadoB;return 0;return 0;

}int transita_B_A(){

cout << "conmutaB->A\n";estado = estadoA;return 0;

}int maquina_fin(){

return 1;}

int (*maquina_de_estados[2][2]) (void) = { &transita_A_B, /* [estadoA][evento0] */&maquina_fin, /* [estadoA][evento1] */&maquina_fin, /* [estadoB][evento0] */&transita_B_A, /* [estadoB][evento1] */

};32

Page 14: FSC Tema3 Recortado

Máquinas de estado (III)

� Implementación con tabla de punteros a funciones (cont.)

int estado; /*variable global que modifican las funciones*/

int main(){

/* ... *//* ... */

estado = estadoA; /*estado inicial*/

bool fin=false;

while(!fin){

int evento;

espera_evento(&evento); /*bloquea*/

fin = maquina_de_estados[estado][evento]();

}

return 0;

}

33

Page 15: FSC Tema3 Recortado

Fundamentos de Software de Comunicaciones

Tema 3Fundamentos de Fundamentos de diseño de capas de protocolos (2ª parte)

Page 16: FSC Tema3 Recortado

Tipos de enteros (estándar C99)� Para evitar problemas de compatibilidad, cuando se migra un

código a distintas plataformas, se debe evitar dependencias con int, short, long, etc.

� #include <stdint.h>o Define tipos de enteros independientes de la plataformauint8_t/int8_tuint8_t/int8_tuint16_t/int16_tuint32_t/int32_tuint64_t/int64_t

� #include <inttypes.h>o Para imprimir de forma correcta estos valores:uint64_t v = 6148914690091192593;printf("valor = %"PRIu64" \n", v);

5

Page 17: FSC Tema3 Recortado

Representación de datos en PDUs� Arquitecturas big-endian o little-endian

o La tabla muestra la representación en memoria del valor hexadecimal 0x0A0B0C0D en dos máquinas con distintas arquitecturas (se han utilizado las direcciones de memoria de la 0x1100 a la 0x1103)

� Si no se especifica lo contrario, los datos de control de más de un byte se transmiten en formato big-endian

6

Page 18: FSC Tema3 Recortado

Representación de datos en PDUs� Normalmente, antes de transmitir por la red, los datos se pasan a

formato big-endian y luego, en recepción, se reconvierten si es necesario (si la arquitectura del receptor es little-endian)

uint16_t cambia_endiannes(uin16_t in){ /*Ejemplo no optimizado para 16 bits*/uint16_t out; uint8_t *p_in = (uint8_t *) &in; uint8_t *p_out = (uint8_t *) &out; p_out[0] = p_in[1]; p_out[1] = p_in[0]; return out; return out;

}/*Detección del tipo de arquitectura de la maquina para saber si hay que convertir el dato al enviar y/o recibir*/uint16_t valor = 0xFF00;uint8_t *puntero= (uint8_t *)&valor;if(*puntero!=0){

/*es big endian*/else

/*es little endian*/

/*NOTA: este algoritmo no se utiliza así realmente, el S.O. tiene un #define con el tipo de arquitectura y la biblioteca de sockets tiene unas funciones para hacer la conversión*/

uint16_t convierte_de_formato_interno_a_big_endian(uint16_t value){#if defined(__LITTLE_ENDIAN_)

return cambia_endiannes(value);#else

return value;#endif} /* en la biblioteca de sockets esta función se llama htons() -conversión de formato host (h) a formato network (n)*/

7

Page 19: FSC Tema3 Recortado

Representación de datos en PDUs� Es tentador organizar una PDU (cabecera+payload) en una

estructura de datos y mandarla como si fuera un array de caracteres:

/*funcion parte del driver de la tarjeta de red que coloca la trama en el buffer circular de DMA*/

int envia_trama(uint8_t * buffer, size_t longitud);

struct Trama_Ethernet{

uint8_t dir_destino[6];

uint8_t dir_origen[6];

uint16_t tipo_protocolo;

uint8_t payload[1500];

};

struct Trama_Ethernet trama = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},{0x01,0x01,0x01,0x01,0x01,0x01},0x0800,0};

envia_trama((uint8_t *)&trama,14+46); /*46 es la longitud minima del payload en Ethernet*/

/*puede funcionar pero, como se verá a continuación, en otros casos podría ser erróneo!!!*/

8

Page 20: FSC Tema3 Recortado

Alineamiento de bytes en estructuras� Cada compilador elige cómo representar una estructura en memoria

o Si el compilador del programa emisor elige una representación distinta al del receptor se producirá una incompatibilidad al serializar/deserializar los datos

o Cada compilador se adapta a la arquitectura del ordenador para el que genera código

� La mayor parte de procesadores de 16, 32 y 64 bits no permiten almacenar palabras en cualquier offset de memoriaalmacenar palabras en cualquier offset de memoria

o Por ejemplo, en procesadores de 32 bits la memoria se accede realizando ciclos de bus de 32 bits (alineando datos de tipo uint32_t sólo en direcciones de memoria divisibles entre cuatro).

9

X0X1X2X3: bien alineadolectura en un ciclo

Y0Y1Y2Y3: mal alineado(necesitaría dos ciclos paraser leído)

Page 21: FSC Tema3 Recortado

Alineamiento de bytes en estructuras� El compilador debe respetar las restricciones de alineamiento del

procesador, por lo que tendrá que añadir bytes de relleno a las estructuras definidas por el programador para cumplir dichas restricciones

struct Mensaje{ /*Estructura definida por el programador*/uint16_t opcode; uint8_t subfield; uint32_t length; uint8_t version; uint8_t version; uint16_t destino;

};

� El compilador internamente cambia a esta estructurastruct Mensaje{ /*Estructura que se compila en realidad*/

uint16_t opcode; uint8_t subfield; uint8_t relleno1; /*relleno para alinear el siguiente campo a 4 bytes*/uint32_t length; uint8_t version; uint8_t relleno2; /*relleno para alinear el siguiente campo a 2 bytes*/uint16_t destino; uint8_t relleno3[4]; /*relleno para alinear la estructura completa en 16 bytes*/

};10

Page 22: FSC Tema3 Recortado

Transmisión de otros tipos complejos

� ¿Qué pasa si el tipo a transmitir no es de tipo entero?

o O se crean reglas a medida

o O se usan estándares (en C/C++ son típicos, pero requieren de librerías y herramientas externas):• ASN.1 + reglas de codificación (ITU-T)• Common Data Representation (OMG)• Otros estándares dentro de una organización:

• Protocol Buffers (Google)

12

Page 23: FSC Tema3 Recortado

Control de errores

� Información redundante para detección de errores que es parte de la parte de control de una PDU

� Habituales en protocolos:� Habituales en protocolos:o checksum: suma de comprobación (típica en

software, eficacia parcial)o CRC: códigos de redundancia cíclica (típica en

hardware, detecta más tipos de errores)

13

Page 24: FSC Tema3 Recortado

Checksum en trailers

comienzode trama

fin de trama

cksumDLE STX datos de usuario DLE ETX

� Típico en PDUs de nivel de enlace

14

de trama trama

DLE(0x10): Data Link EscapeSTX(0x02): Start of TeXtETX(0x03): End of TeXt

Page 25: FSC Tema3 Recortado

Checksums en cabeceras

15

Page 26: FSC Tema3 Recortado

Checksums en TCP/IP

Tareas del emisor: Tareas del receptor:

Objetivo: detectar errores en las cabeceras (caso de IP) o en la PDU completa (caso de ICMP, UDP y TCP)

� manipular la PDU como una secuencia de enteros de 16-bits

� Calcular el campo checksum de la secuencia considerada y añadirlo a la PDU

� calcular el checksum de la secuencia recibida

� Si el checksum calculado es igual al recibido:o NO: hay un erroro SÍ: no se ha detectado

error

16

Page 27: FSC Tema3 Recortado

Cálculo de checksums

� Complemento a uno de la suma de todas las palabras de la secuencia

a. Suma de comprobación en el sitio emisor b. Suma de comprobación en el sitio receptor17

Page 28: FSC Tema3 Recortado

Implementación en C (I)

� Complementos a 1:

c_1 _de_valor = ~ valor;

� Suma en complemento a 1 (ejemplo checksum8):

uint8_t x, y, checksum;

uint16_t suma_parcial, suma; /*...*/

suma_parcial = ((uint16_t)x) + ((uint16_t)y);

suma = (suma_parcial & 0xFF) + (suma_parcial>>8);

checksum = ~suma & 0xFF;

18

Page 29: FSC Tema3 Recortado

Implementación en C (II)� Implementación estándar del checksum 16 bits para IP

19