Réseau
2014-09-26
Ce document combine quatre courts articles :
- 2011-06-17 : Configuration combinée IPv4/IPv6
- 2011-08-31 : Bind de socket et TIME_WAIT
- 2011-09-04 : Configurer un NAT
- 2012-09-29 : Utilisation de epoll
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 :
On commence par initier un socket d’attente epoll :
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 :
- Exemple complet (en)
- man epoll (en)
- Quand epoll() n’existait pas (en)