Exemple #1
0
/*
 * Unfuse a previously-fused pair of tcp loopback endpoints.
 */
void
tcp_unfuse(tcp_t *tcp)
{
	tcp_t *peer_tcp = tcp->tcp_loopback_peer;

	ASSERT(tcp->tcp_fused && peer_tcp != NULL);
	ASSERT(peer_tcp->tcp_fused && peer_tcp->tcp_loopback_peer == tcp);
	ASSERT(tcp->tcp_connp->conn_sqp == peer_tcp->tcp_connp->conn_sqp);
	ASSERT(tcp->tcp_unsent == 0 && peer_tcp->tcp_unsent == 0);
	ASSERT(tcp->tcp_fused_sigurg_mp != NULL);
	ASSERT(peer_tcp->tcp_fused_sigurg_mp != NULL);

	/*
	 * We disable synchronous streams, drain any queued data and
	 * clear tcp_direct_sockfs.  The synchronous streams entry
	 * points will become no-ops after this point.
	 */
	tcp_fuse_disable_pair(tcp, B_TRUE);

	/*
	 * Update th_seq and th_ack in the header template
	 */
	U32_TO_ABE32(tcp->tcp_snxt, tcp->tcp_tcph->th_seq);
	U32_TO_ABE32(tcp->tcp_rnxt, tcp->tcp_tcph->th_ack);
	U32_TO_ABE32(peer_tcp->tcp_snxt, peer_tcp->tcp_tcph->th_seq);
	U32_TO_ABE32(peer_tcp->tcp_rnxt, peer_tcp->tcp_tcph->th_ack);

	/* Unfuse the endpoints */
	peer_tcp->tcp_fused = tcp->tcp_fused = B_FALSE;
	peer_tcp->tcp_loopback_peer = tcp->tcp_loopback_peer = NULL;
}
Exemple #2
0
mblk_t *
sctp_init_mp(sctp_t *sctp, sctp_faddr_t *fp)
{
	mblk_t			*mp;
	uchar_t			*p;
	size_t			initlen;
	sctp_init_chunk_t	*icp;
	sctp_chunk_hdr_t	*chp;
	uint16_t		schlen;
	int			supp_af;
	sctp_stack_t		*sctps = sctp->sctp_sctps;
	conn_t			*connp = sctp->sctp_connp;

	if (connp->conn_family == AF_INET) {
		supp_af = PARM_SUPP_V4;
	} else {
		if (sctp->sctp_connp->conn_ipv6_v6only)
			supp_af = PARM_SUPP_V6;
		else
			supp_af = PARM_SUPP_V6 | PARM_SUPP_V4;
	}
	initlen = sizeof (*chp) + sizeof (*icp);
	if (sctp->sctp_send_adaptation) {
		initlen += (sizeof (sctp_parm_hdr_t) + sizeof (uint32_t));
	}
	initlen += sctp_supaddr_param_len(sctp);
	initlen += sctp_addr_params(sctp, supp_af, NULL, B_TRUE);
	if (sctp->sctp_prsctp_aware && sctps->sctps_prsctp_enabled)
		initlen += sctp_options_param_len(sctp, SCTP_PRSCTP_OPTION);

	/*
	 * This could be a INIT retransmission in which case sh_verf may
	 * be non-zero, zero it out just to be sure.
	 */
	sctp->sctp_sctph->sh_verf = 0;
	sctp->sctp_sctph6->sh_verf = 0;

	mp = sctp_make_mp(sctp, fp, initlen);
	if (mp == NULL) {
		SCTP_KSTAT(sctps, sctp_send_init_failed);
		return (NULL);
	}
	/* sctp_make_mp could have discovered we have no usable sources */
	if (sctp->sctp_nsaddrs == 0) {
		freemsg(mp);
		SCTP_KSTAT(sctps, sctp_send_init_failed);
		return (NULL);
	}

	/* Lay in a new INIT chunk, starting with the chunk header */
	chp = (sctp_chunk_hdr_t *)mp->b_wptr;
	chp->sch_id = CHUNK_INIT;
	chp->sch_flags = 0;
	schlen = (uint16_t)initlen;
	U16_TO_ABE16(schlen, &(chp->sch_len));

	mp->b_wptr += initlen;

	icp = (sctp_init_chunk_t *)(chp + 1);
	icp->sic_inittag = sctp->sctp_lvtag;
	U32_TO_ABE32(sctp->sctp_rwnd, &(icp->sic_a_rwnd));
	U16_TO_ABE16(sctp->sctp_num_ostr, &(icp->sic_outstr));
	U16_TO_ABE16(sctp->sctp_num_istr, &(icp->sic_instr));
	U32_TO_ABE32(sctp->sctp_ltsn, &(icp->sic_inittsn));

	p = (uchar_t *)(icp + 1);

	/* Adaptation layer param */
	p += sctp_adaptation_code_param(sctp, p);

	/* Add supported address types parameter */
	p += sctp_supaddr_param(sctp, p);

	/* Add address parameters */
	p += sctp_addr_params(sctp, supp_af, p, B_FALSE);

	/* Add Forward-TSN-Supported param */
	if (sctp->sctp_prsctp_aware && sctps->sctps_prsctp_enabled)
		p += sctp_options_param(sctp, p, SCTP_PRSCTP_OPTION);

	BUMP_LOCAL(sctp->sctp_obchunks);

	sctp_set_iplen(sctp, mp, fp->sf_ixa);

	return (mp);
}