tcp_sk(sk)->bind_hash = tb;
}
-/*
- Return 1 if addr match the socket IP list
- or the socket is INADDR_ANY
-*/
-static inline int tcp_in_list(struct sock *sk, u32 addr)
-{
- struct nx_info *nxi = sk->sk_nx_info;
-
- vxdprintk(VXD_CBIT(net, 2), "tcp_in_list(%p) %p,%p;%lx",
- sk, nxi, sk->sk_socket,
- (sk->sk_socket?sk->sk_socket->flags:0));
-
- if (nxi) {
- int n = nxi->nbipv4;
- int i;
-
- for (i=0; i<n; i++)
- if (nxi->ipv4[i] == addr)
- return 1;
- }
- else if (!tcp_v4_rcv_saddr(sk) || tcp_v4_rcv_saddr(sk) == addr)
- return 1;
- return 0;
-}
-
-/*
- Check if the addresses in sk1 conflict with those in sk2
-*/
-int tcp_ipv4_addr_conflict(struct sock *sk1, struct sock *sk2)
-{
- if (sk1 && sk2)
- vxdprintk(VXD_CBIT(net, 5),
- "tcp_ipv4_addr_conflict(%p,%p) %p,%p;%lx %p,%p;%lx",
- sk1, sk2,
- sk1->sk_nx_info, sk1->sk_socket,
- (sk1->sk_socket?sk1->sk_socket->flags:0),
- sk2->sk_nx_info, sk2->sk_socket,
- (sk2->sk_socket?sk2->sk_socket->flags:0));
-
- if (tcp_v4_rcv_saddr(sk1)) {
- /* Bind to one address only */
- return tcp_in_list (sk2, tcp_v4_rcv_saddr(sk1));
- } else if (sk1->sk_nx_info) {
- /* A restricted bind(any) */
- struct nx_info *nxi = sk1->sk_nx_info;
- int n = nxi->nbipv4;
- int i;
-
- for (i=0; i<n; i++)
- if (tcp_in_list (sk2, nxi->ipv4[i]))
- return 1;
- } else /* A bind(any) do not allow other bind on the same port */
- return 1;
- return 0;
-}
-
static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
{
struct sock *sk2;
sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
if (!reuse || !sk2->sk_reuse ||
sk2->sk_state == TCP_LISTEN) {
- if (tcp_ipv4_addr_conflict(sk, sk2))
+ if (nx_addr_conflict(sk->sk_nx_info,
+ tcp_v4_rcv_saddr(sk), sk2))
break;
}
}
wake_up(&tcp_lhash_wait);
}
+
/*
- Check if an address is in the list
-*/
-static inline int tcp_addr_in_list(
- u32 rcv_saddr,
- u32 daddr,
- struct nx_info *nx_info)
-{
- if (rcv_saddr == daddr)
+ * Check if a given address matches for a tcp socket
+ *
+ * nxi: the socket's nx_info if any
+ * addr: to be verified address
+ * saddr: socket addresses
+ */
+static inline int tcp_addr_match (
+ struct nx_info *nxi,
+ uint32_t addr,
+ uint32_t saddr)
+{
+ if (addr && (saddr == addr))
return 1;
- else if (rcv_saddr == 0) {
- /* Accept any address or check the list */
- if (!nx_info)
- return 1;
- else {
- int n = nx_info->nbipv4;
- int i;
-
- for (i=0; i<n; i++)
- if (nx_info->ipv4[i] == daddr)
- return 1;
- }
- }
+ if (!saddr)
+ return addr_in_nx_info(nxi, addr);
return 0;
}
-
-
/* Don't inline this cruft. Here are some nice properties to
* exploit here. The BSD API does not allow a listening TCP
* to specify the remote port nor the remote address for the
__u32 rcv_saddr = inet->rcv_saddr;
score = (sk->sk_family == PF_INET ? 1 : 0);
- if (tcp_addr_in_list(rcv_saddr, daddr, sk->sk_nx_info))
+ if (tcp_addr_match(sk->sk_nx_info, daddr, rcv_saddr))
score+=2;
else
continue;
if (inet->num == hnum && !sk->sk_node.next &&
(sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
- tcp_addr_in_list(inet->rcv_saddr, daddr, sk->sk_nx_info) &&
+ tcp_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) &&
!sk->sk_bound_dev_if)
goto sherry_cache;
sk = __tcp_v4_lookup_listener(head, daddr, hnum, dif);
switch (type) {
case ICMP_SOURCE_QUENCH:
- /* This is deprecated, but if someone generated it,
- * we have no reasons to ignore it.
- */
- if (!sock_owned_by_user(sk))
- tcp_enter_cwr(tp);
+ /* Just silently ignore these. */
goto out;
case ICMP_PARAMETERPROB:
err = EPROTO;
*/
tp->snd_ssthresh = 0x7fffffff; /* Infinity */
tp->snd_cwnd_clamp = ~0;
- tp->mss_cache = 536;
+ tp->mss_cache_std = tp->mss_cache = 536;
tp->reordering = sysctl_tcp_reordering;
while (1) {
while (req) {
vxdprintk(VXD_CBIT(net, 6),
- "sk,req: %p [#%d] (from %d)",
- req->sk, req->sk->sk_xid, current->xid);
- if (!vx_check(req->sk->sk_xid, VX_IDENT|VX_WATCH))
+ "sk,req: %p [#%d] (from %d)", req->sk,
+ (req->sk)?req->sk->sk_xid:0, current->xid);
+ if (req->sk &&
+ !vx_check(req->sk->sk_xid, VX_IDENT|VX_WATCH))
continue;
if (req->class->family == st->family) {
cur = req;
sk = sk_next(st->syn_wait_sk);
st->state = TCP_SEQ_STATE_LISTENING;
read_unlock_bh(&tp->syn_wait_lock);
- } else
+ } else {
+ tp = tcp_sk(sk);
+ read_lock_bh(&tp->syn_wait_lock);
+ if (tp->listen_opt && tp->listen_opt->qlen)
+ goto start_req;
+ read_unlock_bh(&tp->syn_wait_lock);
sk = sk_next(sk);
+ }
get_sk:
sk_for_each_from(sk, node) {
vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
tp = tcp_sk(sk);
read_lock_bh(&tp->syn_wait_lock);
if (tp->listen_opt && tp->listen_opt->qlen) {
+start_req:
st->uid = sock_i_uid(sk);
st->syn_wait_sk = sk;
st->state = TCP_SEQ_STATE_OPENREQ;
.sysctl_wmem = sysctl_tcp_wmem,
.sysctl_rmem = sysctl_tcp_rmem,
.max_header = MAX_TCP_HEADER,
+ .slab_obj_size = sizeof(struct tcp_sock),
};