/* This is for all connections with a full identity, no wildcards. *The'e'prefixstandsforEstablish,butwereallyputallsockets *butLISTENones.
*/ struct inet_ehash_bucket { struct hlist_nulls_head chain;
};
/* There are a few simple rules, which allow for local port reuse by *anapplication.Inessence: * *1)Socketsboundtodifferentinterfacesmaysharealocalport. *Failingthat,gototest2. *2)Ifallsocketshavesk->sk_reuseset,andnoneofthemarein *TCP_LISTENstate,theportmaybeshared. *Failingthat,gototest3. *3)Ifallsocketsareboundtoaspecificinet_sk(sk)->rcv_saddrlocal *address,andnoneofthemarethesame,theportmaybe *shared. *Failingthis,theportcannotbeshared. * *Theinterestingpoint,istest#2.ThisiswhatanFTPserverdoes *allday.Tooptimizethiscaseweuseaspecificflagbitdefined *below.Asweaddsocketstoabindbucketlist,weperforma *checkof:(newsk->sk_reuse&&(newsk->sk_state!=TCP_LISTEN)) *Aslongasallsocketsaddedtoabindbucketpassthistest, *theflagbitwillbeset. *Theresultingsituationisthattcp_v[46]_verify_bind()canjustcheck *forthisflagbit,ifitissetandthesockettryingtobindhas *sk->sk_reuseset,wedon'tevenhavetowalktheownerslistatall, *wereturnthatitisoktobindthissockettotherequestedlocalport. * *Soundslikealotofwork,butitisworthit.Inamorenaive *implementation(ie.currentFreeBSDetc.)theentirelistofports *mustbewalkedforeachdataportopenedbyanftpserver.Needless *tosay,thisdoesnotscaleatall.WithacouplethousandFTP *usersloggedontoyourbox,isn'titnicetoknowthatnewdata *portsarecreatedinO(1)time?Ithoughtso.;-)-DaveM
*/ #define FASTREUSEPORT_ANY 1 #define FASTREUSEPORT_STRICT 2
/* Sockets can be hashed in established or listening table. *Wemustusedifferent'nulls'end-of-chainvalueforallhashbuckets: *AsocketmighttransitionfromESTABLISHtoLISTENstatewithout *RCUgraceperiod.Alookupinehashtableneedstohandlethiscase.
*/ #define LISTENING_NULLS_BASE (1U << 29) struct inet_listen_hashbucket {
spinlock_t lock; struct hlist_nulls_head nulls_head;
};
/* This is for listening sockets, thus all sockets which possess wildcards. */ #define INET_LHTABLE_SIZE 32/* Yes, really, this is all you need. */
struct inet_hashinfo { /* This is for sockets with full identity only. Sockets here will *alwaysbewithoutwildcardsandwillhavethefollowinginvariant: * *TCP_ESTABLISHED<=sk->sk_state<TCP_CLOSE *
*/ struct inet_ehash_bucket *ehash;
spinlock_t *ehash_locks; unsignedint ehash_mask; unsignedint ehash_locks_mask;
/* Ok, let's try this, I give up, we do need a local binding *TCPhashaswellastheothersforfastbind/connect.
*/ struct kmem_cache *bind_bucket_cachep; /* This bind table is hashed by local port */ struct inet_bind_hashbucket *bhash; struct kmem_cache *bind2_bucket_cachep; /* This bind table is hashed by local port and sk->sk_rcv_saddr (ipv4) *orsk->sk_v6_rcv_saddr(ipv6).This2ndbindtableisused *primarilyforexpeditingbindconflictresolution.
*/ struct inet_bind_hashbucket *bhash2; unsignedint bhash_size;
/* The 2nd listener table hashed by local port and address */ unsignedint lhash2_mask; struct inet_listen_hashbucket *lhash2;
struct inet_bind_hashbucket *
inet_bhash2_addr_any_hashbucket(conststruct sock *sk, conststruct net *net, int port);
/* This should be called whenever a socket's sk_rcv_saddr (ipv4) or *sk_v6_rcv_saddr(ipv6)changesafterithasbeenbinded.Thesocket's *rcv_saddrfieldshouldalreadyhavebeenupdatedwhenthisiscalled.
*/ int inet_bhash2_update_saddr(struct sock *sk, void *saddr, int family); void inet_bhash2_reset_saddr(struct sock *sk);
staticinlinebool inet_match(conststruct net *net, conststruct sock *sk, const __addrpair cookie, const __portpair ports, int dif, int sdif)
{ if (!net_eq(sock_net(sk), net) ||
sk->sk_portpair != ports ||
sk->sk_addrpair != cookie) returnfalse;
/* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */ return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif,
sdif);
}
/* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need *notcheckitforlookupsanymore,thanksAlexey.-DaveM
*/ struct sock *__inet_lookup_established(conststruct net *net, struct inet_hashinfo *hashinfo, const __be32 saddr, const __be16 sport, const __be32 daddr, const u16 hnum, constint dif, constint sdif);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.