Está en la página 1de 29

Fundamentos de Software de

Comunicaciones
Tema 3
Fundamentos de
diseo de capas de
protocolos (1 parte)

Elementos de diseo e implementacin


Flujo de datos entre capas

Elementos de diseo e implementacin


El mecanismo de funcionamiento de cada protocolo
normalmente se encuentra descrito en un estndar (ITU,
ETSI, RFC, IEEE)
Aspectos de implementacin de capas:
o

Clasificacin en funcin del procesado que realiza el protocolo:


procesado de datos (trabajo sobre payload, por ejemplo
segmentacin, reensamblado)
procesado de control (de la cabecera y de la evolucin del estado del
protocolo en funcin del PCI)
funciones de soporte: procesado de buffers y gestin de
temporizadores

Comunicacin entre capas (I)


PRIMITIVAS OSI/3GPP
Modelo de comunicacin que garantiza la
independencia espacial entre capas
o

No hace suposiciones sobre dnde se ejecuta


cada capa (distintos procesos, nodos...)

N
REQUEST

CONFIRM

N-1
12

N
INDICATION

RESPONSE

N-1

Diseo e implementacin de
arquitecturas de protocolos
A pesar de los estndares de protocolos, hay
muchas cuestiones de diseo e implementacin
que se dejan a los programadores
Por ejemplo: cmo implemento cada capa? En
software? En hardware dedicado?

14

Capas en software
Mapeo 1-a-1
o

Cada capa es una unidad funcional (por ejemplo


un proceso)
Necesidades: colas de mensajes y distincin de
mensajes que van en sentido "downlink" o "uplink"

Atender a un mensaje se realiza de forma asncrona:


la capa que enva el mensaje sigue su ejecucin, la
capa que lo recibe, lo atiende cuando lo desencola.
Algoritmo:
while(1){
espera_evento(&evento);
procesa_evento(evento);
}

15

Gestin de mensajes entre capas


El mismo buffer se utiliza para guardar todas las
cabeceras y payload
El tamao mximo del buffer es el MTU de la red
Ejemplo de uso para PDUs en sentido
descendente:

19

Gestin de mensajes entre capas (II)

char * pduN

char * pduN_1

char * pduN_2

20

Elementos de soporte

gestor de
temporizadores

Inserta trama y
genera interrrupcin

NIC

22

BUFFER
CIRCULAR

Atiende a la interrupcin y crea


un buffer donde copia la trama

ZONA DE DMA

Diseo e implementacin de la parte de control


Se utilizan mquinas de estados finitos
o

Se implementa un autmata que decide las funciones a


realizar en el protocolo, a partir de
el estado actual del autmata
la informacin de control del protocolo recibida en un paquete
el resultado de procesar los datos

Se pasa de un estado a otro cuando se reciben eventos


llegada de paquetes o eventos de tiempo (timeouts)

Se vern varias tcnicas de implementacin de una mquina


de estados:
basada en cdigo (con dos bucles anidados IF o SWITCH/CASE)
basada en tablas (array dos dimensiones: [estado][evento])

Protocolos y mquinas de estados


Cuando un protocolo tiene estado, se necesita implementar
su comportamiento mediante una mquina de estados

En programacin imperativa existen dos aproximaciones:


1.

Lineal: a travs de sentencias anidadas

2.

30

switch(estado)/case { switch(evento)/case}
rpido, poco modular

Tabla de punteros a funcin manejadora

protocolo[estado][evento](argumentos)
costoso en memoria, pero modular

Mquinas de estado (I)


Implementacin 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";
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

}
}

Mquinas de estado (II)


Implementacin 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;
}
int transita_B_A(){
cout << "conmutaB->A\n";
estado = estadoA;
return 0;
}
int maquina_fin(){
return 1;
}

32

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]
};

*/
*/
*/
*/

Mquinas de estado (III)


Implementacin 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

Fundamentos de Software de
Comunicaciones
Tema 3
Fundamentos de
diseo de capas de
protocolos (2 parte)

Tipos de enteros (estndar C99)


Para evitar problemas de compatibilidad, cuando se migra un
cdigo a distintas plataformas, se debe evitar dependencias
con int, short, long, etc.
#include <stdint.h>
Define tipos de enteros independientes de la plataforma
uint8_t/int8_t
uint16_t/int16_t
uint32_t/int32_t
uint64_t/int64_t
o

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

Representacin de datos en PDUs


Arquitecturas big-endian o little-endian
o

La tabla muestra la representacin en memoria del valor


hexadecimal 0x0A0B0C0D en dos mquinas 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 ms


de un byte se transmiten en formato big-endian

Representacin de datos en PDUs


Normalmente, antes de transmitir por la red, los datos se pasan a
formato big-endian y luego, en recepcin, 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;
}
/*Deteccin 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 conversin*/
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 funcin se llama htons() -conversin de formato host (h) a formato network (n)*/

Representacin 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 continuacin, en otros casos podra ser errneo!!!*/

Alineamiento de bytes en estructuras


Cada compilador elige cmo representar una estructura en memoria
o

Si el compilador del programa emisor elige una representacin distinta al


del receptor se producir una incompatibilidad al serializar/deserializar
los datos
Cada compilador se adapta a la arquitectura del ordenador para el que
genera cdigo

La mayor parte de procesadores de 16, 32 y 64 bits no permiten


almacenar 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 slo
en direcciones de memoria divisibles entre cuatro).

X0X1X2X3: bien alineado


lectura en un ciclo
Y0Y1Y2Y3: mal alineado
(necesitara dos ciclos para
ser ledo)
9

Alineamiento de bytes en estructuras


El compilador debe respetar las restricciones de alineamiento del
procesador, por lo que tendr que aadir 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;
uint16_t destino;
};

El compilador internamente cambia a esta estructura


struct 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

Transmisin de otros tipos complejos


Qu pasa si el tipo a transmitir no es de
tipo entero?
o

O se crean reglas a medida

O se usan estndares (en C/C++ son tpicos,


pero requieren de libreras y herramientas
externas):
ASN.1 + reglas de codificacin (ITU-T)
Common Data Representation (OMG)
Otros estndares dentro de una organizacin:
Protocol Buffers (Google)

12

Control de errores
Informacin redundante para deteccin de
errores que es parte de la parte de control
de una PDU
Habituales en protocolos:
o

13

checksum: suma de comprobacin (tpica en


software, eficacia parcial)
CRC: cdigos de redundancia cclica (tpica en
hardware, detecta ms tipos de errores)

Checksum en trailers

DLE STX
comienzo
de trama

datos de usuario DLE ETX cksum


fin de
trama

DLE(0x10): Data Link Escape


STX(0x02): Start of TeXt
ETX(0x03): End of TeXt

Tpico en PDUs de nivel de enlace


14

Checksums en cabeceras

15

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

Tareas del emisor:


manipular la PDU como
una secuencia de
enteros de 16-bits
Calcular el campo
checksum de la
secuencia considerada y
aadirlo a la PDU

16

Tareas del receptor:


calcular el checksum de la
secuencia recibida
Si el checksum calculado
es igual al recibido:
o NO: hay un error
o S: no se ha detectado
error

Clculo de checksums
Complemento a uno de la suma de todas
las palabras de la secuencia

17

a. Suma de comprobacin en el sitio emisor

b. Suma de comprobacin en el sitio receptor

Implementacin 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

Implementacin en C (II)
Implementacin estndar del checksum 16 bits para IP

19

También podría gustarte