This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <strings.h> | |
#include <sys/wait.h> | |
#include <netdb.h> | |
void create_children(int nprocs, int parent_pid) | |
{ | |
while (nprocs-- > 0) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <sys/wait.h> | |
#include <netdb.h> | |
void create_children(int nprocs, int parent_pid) | |
{ | |
while (nprocs-- > 0) { | |
if (getpid() == parent_pid && fork() < 0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Server is listening on port #45000 | |
$ ss -tan | grep :45000 | |
LISTEN 0 1 10.20.1.1:45000 *:* | |
# A client connects to the server using it's source port 54762. A new | |
# socket is created and is seen in ESTABLISHED state, along with the | |
# earlier LISTEN socket. | |
$ ss -tan | grep :45000 | |
LISTEN 0 1 10.20.1.1:45000 *:* | |
ESTAB 0 0 10.20.1.1:45000 10.20.1.100:54762 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define LHTABLE_SIZE 32 /* Yes, really, this is all you need */ | |
struct inet_hashinfo { | |
/* Hash table for fully established sockets */ | |
struct inet_ehash_bucket *ehash; | |
/* Hash table for LISTEN sockets */ | |
struct inet_listen_hashbucket listening_hash[LHTABLE_SIZE]; | |
}; | |
struct inet_hashinfo tcp_hashinfo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct sock *__inet_lookup_skb(tcp_hashinfo, skb, src_port, dst_port) | |
{ | |
/* Get the IPv4 header to know the source and destination IP's */ | |
const struct iphdr *iph = ip_hdr(skb); | |
/* | |
* Look up the incoming skb in tcp_hashinfo using the | |
* [ Source-IP:Port, Destination-IP:Port ] tuple. | |
*/ | |
return __inet_lookup(tcp_hashinfo, skb, iph->saddr, src_port, iph->daddr, dst_port); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct sock *__inet_lookup(tcp_hashinfo, skb, src_addr, src_port, dst_addr, dst_port) | |
{ | |
/* Convert dest_port# from network to host byte order */ | |
u16 hnum = ntohs(dst_port); | |
/* First look for an established socket ... */ | |
sk = __inet_lookup_established(tcp_hashinfo, src_addr, src_port, dst_addr, hnum); | |
if (sk) | |
return sk; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct sock *__inet_lookup_listener(tcp_hashinfo, skb, src_addr, src_port, dst_addr, dst_port) | |
{ | |
/* | |
* Use the destination port# to calculate a hash table slot# of the listen socket. | |
* inet_lhashfn() returns a number between 0 and INET_LHTABLE_SIZE-1 (both | |
* inclusive). | |
*/ | |
unsigned int hash = inet_lhashfn(dst_port); | |
/* Use this hash slot# to index the global LISTEN hash table */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct sock *reuseport_select_sock(struct sock *sk, unsigned int phash) | |
{ | |
/* Get control block of sockets in this SO_REUSEPORT group */ | |
struct sock_reuseport *reuse = sk->sk_reuseport_cb; | |
/* Get count of sockets in the group */ | |
int num_socks = reuse->num_socks; | |
/* Calculate value between 0 and 'num_socks-1' (both inclusive) */ | |
unsigned int index = reciprocal_scale(phash, num_socks); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct sock_reuseport { | |
u16 max_socks; /* Allocated size of socks[] array */ | |
u16 num_socks; /* #Elements in socks[] */ | |
struct sock *socks[0]; /* All sockets added to this group */ | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static int inet_reuseport_add_sock(struct sock *new_sk) | |
{ | |
/* First check if another identical LISTEN socket, prev_sk, | |
* exists. ... Then do the following: | |
*/ | |
if (prev_sk) { | |
/* | |
* Not the first listener - do the following: | |
* - Grow prev_sk->sk_reuseport_cb structure if required. | |
* - Save new_sk socket pointer in prev_sk's socks[]. |
OlderNewer