Réseau

2014-09-26

Ce document combine quatre courts articles :

Ces indications sont valables pour Debian et dérivés (par ex. Ubuntu).

Configuration

Adresse IPv6 statique

Dans /etc/network/interfaces :

auto eth0
    ...
    up ip addr add dev eth0 2001:db8:0:85f3::1/64

NAT

# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE

Pour rendre ces modifications rémanentes :

  • ajouter la ligne : net.ipv4.ip_forward=1 dans /etc/sysctl.conf
  • ajouter pre-up iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE dans /etc/network/interfaces

Programmation

Réutilisation de port

Par défaut, un socket refermé reste occupé en mode TIME_WAIT lors de sa fermeture. Pour éviter un délai, il faut activer l'option SO_REUSEADDR avant l'appel à bind() :

int v=1;
setsockopt(mTCPSocket, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(int));
bind(mTCPSocket, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

Écoute simultanée

Les fonctions select() et poll() permettent de surveiller plusieurs sockets serveurs simultanément. Contrairement à ces deux fonctions, epoll() permet en plus de savoir combien de sockets sont actifs.

L'en-tête nécessaire :

#include <sys/epoll.h>

On commence par initier un socket d'attente epoll :

int epollfd = epoll_create(n_socokets);

Pour chaque socket à surveiller :

struct epoll_event  ev;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epollfd, EPOLL_CTL_ADD, s->fd[i], &ev);

Les champs ev.data.* sont conservés lors du traitement de l'évènement et permettent par exemple d'identifier le socket ou le client concerné :

Champ Type
ev.data.ptr void*
ev.data.fd int
ev.data.u32 __uint32
ev.data.u64 __uint64

Pour attendre des données (timeout est en millisecondes) :

struct epoll_event events[10];
int n_events = epoll_wait(epollfd, events, 10, timeout);
for (int i = 0; i < n_events; i++)
{
    handleClient(events[i].data.u32);
}

Pour plus d'informations :