3910 tcps->tcps_mibkp = NULL;
3911
3912 ldi_ident_release(tcps->tcps_ldi_ident);
3913 kmem_free(tcps, sizeof (*tcps));
3914 }
3915
3916 /*
3917 * Generate ISS, taking into account NDD changes may happen halfway through.
3918 * (If the iss is not zero, set it.)
3919 */
3920
3921 static void
3922 tcp_iss_init(tcp_t *tcp)
3923 {
3924 MD5_CTX context;
3925 struct { uint32_t ports; in6_addr_t src; in6_addr_t dst; } arg;
3926 uint32_t answer[4];
3927 tcp_stack_t *tcps = tcp->tcp_tcps;
3928 conn_t *connp = tcp->tcp_connp;
3929
3930 tcps->tcps_iss_incr_extra += (ISS_INCR >> 1);
3931 tcp->tcp_iss = tcps->tcps_iss_incr_extra;
3932 switch (tcps->tcps_strong_iss) {
3933 case 2:
3934 mutex_enter(&tcps->tcps_iss_key_lock);
3935 context = tcps->tcps_iss_key;
3936 mutex_exit(&tcps->tcps_iss_key_lock);
3937 arg.ports = connp->conn_ports;
3938 arg.src = connp->conn_laddr_v6;
3939 arg.dst = connp->conn_faddr_v6;
3940 MD5Update(&context, (uchar_t *)&arg, sizeof (arg));
3941 MD5Final((uchar_t *)answer, &context);
3942 tcp->tcp_iss += answer[0] ^ answer[1] ^ answer[2] ^ answer[3];
3943 /*
3944 * Now that we've hashed into a unique per-connection sequence
3945 * space, add a random increment per strong_iss == 1. So I
3946 * guess we'll have to...
3947 */
3948 /* FALLTHRU */
3949 case 1:
3950 tcp->tcp_iss += (gethrtime() >> ISS_NSEC_SHT) + tcp_random();
3951 break;
3952 default:
3953 tcp->tcp_iss += (uint32_t)gethrestime_sec() * ISS_INCR;
3954 break;
3955 }
3956 tcp->tcp_valid_bits = TCP_ISS_VALID;
3957 tcp->tcp_fss = tcp->tcp_iss - 1;
3958 tcp->tcp_suna = tcp->tcp_iss;
3959 tcp->tcp_snxt = tcp->tcp_iss + 1;
3960 tcp->tcp_rexmit_nxt = tcp->tcp_snxt;
3961 tcp->tcp_csuna = tcp->tcp_snxt;
3962 }
3963
3964 /*
3965 * tcp_{set,clr}qfull() functions are used to either set or clear QFULL
3966 * on the specified backing STREAMS q. Note, the caller may make the
3967 * decision to call based on the tcp_t.tcp_flow_stopped value which
3968 * when check outside the q's lock is only an advisory check ...
3969 */
3970 void
3971 tcp_setqfull(tcp_t *tcp)
3972 {
3973 tcp_stack_t *tcps = tcp->tcp_tcps;
|
3910 tcps->tcps_mibkp = NULL;
3911
3912 ldi_ident_release(tcps->tcps_ldi_ident);
3913 kmem_free(tcps, sizeof (*tcps));
3914 }
3915
3916 /*
3917 * Generate ISS, taking into account NDD changes may happen halfway through.
3918 * (If the iss is not zero, set it.)
3919 */
3920
3921 static void
3922 tcp_iss_init(tcp_t *tcp)
3923 {
3924 MD5_CTX context;
3925 struct { uint32_t ports; in6_addr_t src; in6_addr_t dst; } arg;
3926 uint32_t answer[4];
3927 tcp_stack_t *tcps = tcp->tcp_tcps;
3928 conn_t *connp = tcp->tcp_connp;
3929
3930 tcps->tcps_iss_incr_extra += (tcps->tcps_iss_incr >> 1);
3931 tcp->tcp_iss = tcps->tcps_iss_incr_extra;
3932 switch (tcps->tcps_strong_iss) {
3933 case 2:
3934 mutex_enter(&tcps->tcps_iss_key_lock);
3935 context = tcps->tcps_iss_key;
3936 mutex_exit(&tcps->tcps_iss_key_lock);
3937 arg.ports = connp->conn_ports;
3938 arg.src = connp->conn_laddr_v6;
3939 arg.dst = connp->conn_faddr_v6;
3940 MD5Update(&context, (uchar_t *)&arg, sizeof (arg));
3941 MD5Final((uchar_t *)answer, &context);
3942 tcp->tcp_iss += answer[0] ^ answer[1] ^ answer[2] ^ answer[3];
3943 /*
3944 * Now that we've hashed into a unique per-connection sequence
3945 * space, add a random increment per strong_iss == 1. So I
3946 * guess we'll have to...
3947 */
3948 /* FALLTHRU */
3949 case 1:
3950 tcp->tcp_iss += (gethrtime() >> ISS_NSEC_SHT) + tcp_random();
3951 break;
3952 default:
3953 tcp->tcp_iss += (uint32_t)gethrestime_sec() *
3954 tcps->tcps_iss_incr;
3955 break;
3956 }
3957 tcp->tcp_valid_bits = TCP_ISS_VALID;
3958 tcp->tcp_fss = tcp->tcp_iss - 1;
3959 tcp->tcp_suna = tcp->tcp_iss;
3960 tcp->tcp_snxt = tcp->tcp_iss + 1;
3961 tcp->tcp_rexmit_nxt = tcp->tcp_snxt;
3962 tcp->tcp_csuna = tcp->tcp_snxt;
3963 }
3964
3965 /*
3966 * tcp_{set,clr}qfull() functions are used to either set or clear QFULL
3967 * on the specified backing STREAMS q. Note, the caller may make the
3968 * decision to call based on the tcp_t.tcp_flow_stopped value which
3969 * when check outside the q's lock is only an advisory check ...
3970 */
3971 void
3972 tcp_setqfull(tcp_t *tcp)
3973 {
3974 tcp_stack_t *tcps = tcp->tcp_tcps;
|