/* Set up ip4/udp headers. The dest addr and ports are not set and * there are no IP options. The source port is defaulted to port 0 */ static void ci_udp_hdrs_init(ci_ip_cached_hdrs* ipcache) { /* Caller should already have done ci_ip_cache_init(). */ ci_ip_hdr_init_fixed(&ipcache->ip, IPPROTO_UDP, CI_IP_DFLT_TTL, CI_IP_DFLT_TOS); ipcache->ip.ip_saddr_be32 = 0; ipcache->ip.ip_daddr_be32 = 0; }
/* Set the IP TOS */ void ci_udp_set_tos( ci_udp_state* us, ci_uint32 tos ) { ci_ip_hdr_init_fixed(UDP_IP_HDR(us), IPPROTO_UDP, UDP_IP_HDR(us)->ip_ttl, CI_MIN(tos, CI_IP_MAX_TOS)); }
/*! Copy socket options and related fields that should be inherited. * Inherits into [ts] from [s] & [c]. Options are inherited during EP * promotion for unix, during accept handler in Windows & as a result of * setsockopt:SOL_SOCKET:SO_UPDATE_ACCEPT_CONTEXT. MUST have a lock on * [ts]. [or_nonblock] controls whether the non-blocking state from [s] * overwrites that in [ts] or is OR'd into it. */ static void ci_tcp_inherit_options(ci_netif* ni, ci_sock_cmn* s, ci_tcp_socket_cmn* c, ci_tcp_state* ts, const char* ctxt) { ci_assert(ni); ci_assert(s); ci_assert(c); ci_assert(ts); ts->s.so = s->so; ts->s.cp.so_bindtodevice = s->cp.so_bindtodevice; ts->s.cp.ip_ttl = s->cp.ip_ttl; ts->s.rx_bind2dev_ifindex = s->rx_bind2dev_ifindex; ts->s.rx_bind2dev_base_ifindex = s->rx_bind2dev_base_ifindex; ts->s.rx_bind2dev_vlan = s->rx_bind2dev_vlan; ci_tcp_set_sndbuf(ni, ts); /* eff_mss must be valid */ ci_tcp_set_rcvbuf(ni, ts); /* and amss, and rcv_wscl */ { /* NB. We have exclusive access to [ts], so it is safe to manipulate ** s_aflags without using bit-ops. */ unsigned inherited_sflags = CI_SOCK_AFLAG_TCP_INHERITED; unsigned inherited_sbflags = 0; if( NI_OPTS(ni).accept_inherit_nonblock ) inherited_sbflags |= CI_SB_AFLAG_O_NONBLOCK | CI_SB_AFLAG_O_NDELAY; ci_assert((ts->s.s_aflags & inherited_sflags) == 0); ci_atomic32_or(&ts->s.s_aflags, s->s_aflags & inherited_sflags); if( NI_OPTS(ni).tcp_force_nodelay == 1 ) ci_bit_set(&ts->s.s_aflags, CI_SOCK_AFLAG_NODELAY_BIT); else if( NI_OPTS(ni).tcp_force_nodelay == 2 ) ci_bit_clear(&ts->s.s_aflags, CI_SOCK_AFLAG_NODELAY_BIT); ci_assert((ts->s.b.sb_aflags & inherited_sbflags) == 0); ci_atomic32_or(&ts->s.b.sb_aflags, s->b.sb_aflags & inherited_sbflags); ci_assert_equal((ts->s.s_flags & CI_SOCK_FLAG_TCP_INHERITED), CI_SOCK_FLAG_PMTU_DO); ts->s.s_flags &= ~CI_SOCK_FLAG_PMTU_DO; ts->s.s_flags |= s->s_flags & CI_SOCK_FLAG_TCP_INHERITED; } /* Bug1861: while not defined as such, various SOL_TCP/SOL_IP sockopts * are inherited in Linux. */ /* TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT */ ts->c.t_ka_time = c->t_ka_time; ts->c.t_ka_time_in_secs = c->t_ka_time_in_secs; ts->c.t_ka_intvl = c->t_ka_intvl; ts->c.t_ka_intvl_in_secs = c->t_ka_intvl_in_secs; ts->c.ka_probe_th = c->ka_probe_th; ci_ip_hdr_init_fixed(&ts->s.pkt.ip, IPPROTO_TCP, s->pkt.ip.ip_ttl, s->pkt.ip.ip_tos); ts->s.cmsg_flags = s->cmsg_flags; ts->s.timestamping_flags = s->timestamping_flags; /* Must have set up so.sndbuf */ ci_tcp_init_rcv_wnd(ts, ctxt); }