⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tp_input.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
				tp_newsocket(so, faddr, cons_channel, 					class_to_use, 					((tpcb->tp_netservice == IN_CLNS) ? IN_CLNS :					(dgout_routine == tpcons_output)?ISO_CONS:ISO_CLNS))					) == (struct socket *)0 ) {				/* note - even if netservice is IN_CLNS, as far as				 * the tp entity is concerned, the only differences				 * are CO vs CL				 */				IFDEBUG(D_CONN)					printf("tp_newsocket returns 0\n");				ENDDEBUG				goto discard;			clear_parent_tcb:				tpcb = 0;				goto respond;			}			tpcb = sototpcb(so);			insque(tpcb, parent_tpcb);			/*			 * Stash the addresses in the net level pcb 			 * kind of like a pcbconnect() but don't need			 * or want all those checks.			 */			(tpcb->tp_nlproto->nlp_putnetaddr)(tpcb->tp_npcb, faddr, TP_FOREIGN);			(tpcb->tp_nlproto->nlp_putnetaddr)(tpcb->tp_npcb, laddr, TP_LOCAL);			/* stash the f suffix in the new tpcb */			if (tpcb->tp_fsuffixlen = fsufxlen) {				bcopy(fsufxloc, tpcb->tp_fsuffix, fsufxlen);				(tpcb->tp_nlproto->nlp_putsufx)						(tpcb->tp_npcb, fsufxloc, fsufxlen, TP_FOREIGN);			}			/* stash the l suffix in the new tpcb */			tpcb->tp_lsuffixlen = lsufxlen;			bcopy(lsufxloc, tpcb->tp_lsuffix, lsufxlen);			(tpcb->tp_nlproto->nlp_putsufx)					(tpcb->tp_npcb, lsufxloc, lsufxlen, TP_LOCAL);#ifdef TP_PERF_MEAS			if( tpcb->tp_perf_on = perf_meas ) { /* assignment */				/* ok, let's create an mbuf for stashing the				 * statistics if one doesn't already exist 				 */				(void) tp_setup_perf(tpcb);			}#endif /* TP_PERF_MEAS */			tpcb->tp_fref = sref;			/* We've already checked for consistency with the options 			 * set in tpp,  but we couldn't set them earlier because 			 * we didn't want to change options in the LISTENING tpcb.			 * Now we set the options in the new socket's tpcb.			 */			(void) tp_consistency( tpcb, TP_FORCE, &tpp);			if(!tpcb->tp_use_checksum)				IncStat(ts_csum_off);			if(tpcb->tp_xpd_service)				IncStat(ts_use_txpd);			if(tpcb->tp_xtd_format)				IncStat(ts_xtd_fmt);			tpcb->tp_peer_acktime = acktime;			/* 			 * The following kludge is used to test retransmissions and 			 * timeout during connection establishment.			 */			IFDEBUG(D_ZDREF)				IncStat(ts_zdebug);				/*tpcb->tp_fref = 0;*/			ENDDEBUG		}		LOCAL_CREDIT(tpcb);		IncStat(ts_CR_rcvd);		if (!tpcb->tp_cebit_off) {			tpcb->tp_win_recv = tp_start_win << 8;			tpcb->tp_cong_sample.cs_size = 0;			CONG_INIT_SAMPLE(tpcb);			CONG_UPDATE_SAMPLE(tpcb, ce_bit);		}	} else if ( dutype == ER_TPDU_type ) {		/* 		 * ER TPDUs have to be recognized separately		 * because they don't necessarily have a tpcb		 * with them and we don't want err out looking for such		 * a beast.		 * We could put a bunch of little kludges in the 		 * next section of code so it would avoid references to tpcb		 * if dutype == ER_TPDU_type but we don't want code for ERs to		 * mess up code for data transfer.		 */		IncStat(ts_ER_rcvd);		e.ev_number = ER_TPDU;		e.ATTR(ER_TPDU).e_reason =  (u_char)hdr->tpdu_ERreason;		CHECK (((int)dref <= 0 || dref >= tp_refinfo.tpr_size || 			(tpcb = tp_ref[dref].tpr_pcb ) == (struct tp_pcb *) 0 ||			tpcb->tp_refstate == REF_FREE ||			tpcb->tp_refstate == REF_FROZEN),		       E_TP_MISM_REFS, ts_inv_dref, discard, 0)	} else {		/* tpdu type is CC, XPD, XAK, GR, AK, DR, DC, or DT */		/* In the next 4 checks,		 * _tpduf is the fixed part; add 2 to get the dref bits of 		 * the fixed part (can't take the address of a bit field) 		 */#ifdef TPCONS		if (cons_channel && dutype == DT_TPDU_type) {			struct isopcb *isop = ((struct isopcb *)				((struct pklcd *)cons_channel)->lcd_upnext);			if (isop && isop->isop_refcnt == 1 && isop->isop_socket &&				(tpcb = sototpcb(isop->isop_socket)) &&				 (tpcb->tp_class == TP_CLASS_0/* || == CLASS_1 */)) {				IFDEBUG(D_TPINPUT)					printf("tpinput_dt: class 0 short circuit\n");				ENDDEBUG				dref = tpcb->tp_lref;				sref = tpcb->tp_fref;				CHECK( (tpcb->tp_refstate == REF_FREE), 					E_TP_MISM_REFS,ts_inv_dref, nonx_dref,					(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))				goto tp0_data;			}		}#endif		{			CHECK( ((int)dref <= 0 || dref >= tp_refinfo.tpr_size) ,				E_TP_MISM_REFS,ts_inv_dref, nonx_dref,				(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))			CHECK( ((tpcb = tp_ref[dref].tpr_pcb ) == (struct tp_pcb *) 0 ), 				E_TP_MISM_REFS,ts_inv_dref, nonx_dref,				(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))			CHECK( (tpcb->tp_refstate == REF_FREE), 				E_TP_MISM_REFS,ts_inv_dref, nonx_dref,				(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))		}		IFDEBUG(D_TPINPUT)			printf("HAVE A TPCB 2: 0x%x\n", tpcb);		ENDDEBUG		/* causes a DR to be sent for CC; ER for all else */		CHECK( (tpcb->tp_refstate == REF_FROZEN),			(dutype == CC_TPDU_type?E_TP_NO_SESSION:E_TP_MISM_REFS),			ts_inv_dref, respond,			(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))		IFDEBUG(D_TPINPUT)			printf("state of dref %d ok, tpcb 0x%x\n", dref,tpcb);		ENDDEBUG		/* 		 * At this point the state of the dref could be		 * FROZEN: tpr_pcb == NULL,  has ( reference only) timers		 *		   for example, DC may arrive after the close() has detached		 *         the tpcb (e.g., if user turned off SO_LISTEN option)		 * OPENING : a tpcb exists but no timers yet		 * OPEN  : tpcb exists & timers are outstanding		 */        if (!tpcb->tp_cebit_off)            CONG_UPDATE_SAMPLE(tpcb, ce_bit);		dusize = tpcb->tp_tpdusize;		pdusize = tpcb->tp_ptpdusize;		dutype = hdr->tpdu_type << 8; /* for the switch below */ 		WHILE_OPTIONS(P, hdr, tpcb->tp_xtd_format) /* { */#define caseof(x,y) case (((x)<<8)+(y))		switch( dutype | vbptr(P)->tpv_code ) {			caseof( CC_TPDU_type, TPP_addl_opt ): 					/* not in class 0; 1 octet */					vb_getval(P, u_char, addlopt);					break;			caseof( CC_TPDU_type, TPP_tpdu_size ): 				{					u_char odusize = dusize;					vb_getval(P, u_char, dusize);					CHECK( (dusize < TP_MIN_TPDUSIZE ||							dusize > TP_MAX_TPDUSIZE || dusize > odusize),						E_TP_INV_PVAL, ts_inv_pval, respond,						(1 + (caddr_t)&vbptr(P)->tpv_val - (caddr_t)hdr) )					IFDEBUG(D_TPINPUT)						printf("CC dusize 0x%x\n", dusize);					ENDDEBUG				}					break;			caseof( CC_TPDU_type, TPP_ptpdu_size ): 				{					u_short opdusize = pdusize;					switch (vbptr(P)->tpv_len) {					case 1: pdusize = vbval(P, u_char); break;					case 2: pdusize = ntohs(vbval(P, u_short)); break;					default: ;					IFDEBUG(D_TPINPUT)						printf("malformed prefered TPDU option\n");					ENDDEBUG					}					CHECK( (pdusize == 0 ||							(opdusize && (pdusize > opdusize))),						E_TP_INV_PVAL, ts_inv_pval, respond,						(1 + (caddr_t)&vbptr(P)->tpv_val - (caddr_t)hdr) )				}					break;			caseof( CC_TPDU_type, TPP_calling_sufx):					IFDEBUG(D_TPINPUT)						printf("CC calling (local) sufxlen 0x%x\n", lsufxlen);					ENDDEBUG					lsufxloc = (caddr_t) &vbptr(P)->tpv_val;					lsufxlen = vbptr(P)->tpv_len;					break;			caseof(	CC_TPDU_type, TPP_acktime ):					/* class 4 only, 2 octets */					vb_getval(P, u_short, acktime);					acktime = ntohs(acktime);					acktime = acktime/500; /* convert to slowtimo ticks */					if( (short)acktime <=0 )						acktime = 2;					break;			caseof(	CC_TPDU_type, TPP_called_sufx):					fsufxloc = (caddr_t) &vbptr(P)->tpv_val;					fsufxlen = vbptr(P)->tpv_len;					IFDEBUG(D_TPINPUT)						printf("CC called (foreign) sufx len %d\n", fsufxlen);					ENDDEBUG					break;			caseof( CC_TPDU_type,	TPP_checksum):					caseof( DR_TPDU_type,	TPP_checksum):					caseof( DT_TPDU_type,	TPP_checksum):					caseof( XPD_TPDU_type,	TPP_checksum):							if( tpcb->tp_use_checksum )  {						CHECK( iso_check_csum(m, tpdu_len), 							E_TP_INV_PVAL, ts_bad_csum, discard, 0)					}					break;			/*  this is different from the above because in the context			 *  of concat/ sep tpdu_len might not be the same as hdr len 			 */			caseof( AK_TPDU_type,	TPP_checksum):					caseof( XAK_TPDU_type,	TPP_checksum):					caseof( DC_TPDU_type,	TPP_checksum):							if( tpcb->tp_use_checksum )  {						CHECK( iso_check_csum(m, (int)hdr->tpdu_li + 1), 							E_TP_INV_PVAL, ts_bad_csum, discard, 0)					}					break;#ifdef notdef			caseof( DR_TPDU_type, TPP_addl_info ):				/* ignore - its length and meaning are				 * user defined and there's no way				 * to pass this info to the user anyway				 */				break;#endif /* notdef */			caseof( AK_TPDU_type, TPP_subseq ):				/* used after reduction of window */				vb_getval(P, u_short, subseq);				subseq = ntohs(subseq);				IFDEBUG(D_ACKRECV)					printf("AK dref 0x%x Subseq 0x%x\n", dref, subseq);				ENDDEBUG				break;			caseof( AK_TPDU_type, TPP_flow_cntl_conf ):				{					u_int 	ylwe;					u_short ysubseq, ycredit;					fcc_present = TRUE;					vb_getval(P, u_int,	 	ylwe);					vb_getval(P, u_short, 	ysubseq);					vb_getval(P, u_short, 	ycredit);					ylwe = ntohl(ylwe);					ysubseq = ntohs(ysubseq);					ycredit = ntohs(ycredit);					IFDEBUG(D_ACKRECV)						printf("%s%x, subseq 0x%x, cdt 0x%x dref 0x%x\n", 							"AK FCC lwe 0x", ylwe, ysubseq, ycredit, dref);					ENDDEBUG				}				break;			default: 				IFDEBUG(D_TPINPUT)					printf("param ignored dutype 0x%x, code  0x%x\n",						dutype, vbptr(P)->tpv_code);				ENDDEBUG				IFTRACE(D_TPINPUT)					tptrace(TPPTmisc, "param ignored dutype code ",						dutype, vbptr(P)->tpv_code ,0,0);				ENDTRACE				IncStat(ts_param_ignored);				break;#undef caseof		}		/* } */ END_WHILE_OPTIONS(P)		/* NOTE: the variable dutype has been shifted left! */		switch( hdr->tpdu_type ) {		case CC_TPDU_type: 			/* If CC comes back with an unacceptable class			 * respond with a DR or ER			 */			opt = hdr->tpdu_CCoptions; /* 1 byte */			{				tpp = tpcb->_tp_param;				tpp.p_class = (1<<hdr->tpdu_CCclass);				tpp.p_tpdusize = dusize;				tpp.p_ptpdusize = pdusize;				tpp.p_dont_change_params = 0;				tpp.p_xtd_format = (opt & TPO_XTD_FMT) == TPO_XTD_FMT;				tpp.p_xpd_service = (addlopt & TPAO_USE_TXPD) == TPAO_USE_TXPD;				tpp.p_use_checksum = (addlopt & TPAO_NO_CSUM) == 0;#ifdef notdef				tpp.p_use_efc = (opt & TPO_USE_EFC) == TPO_USE_EFC;				tpp.p_use_nxpd = (addlopt & TPAO_USE_NXPD) == TPAO_USE_NXPD;				tpp.p_use_rcc = (addlopt & TPAO_USE_RCC) == TPAO_USE_RCC;#endif /* notdef */			CHECK(				tp_consistency(tpcb, TP_FORCE, &tpp) != 0, 				E_TP_NEGOT_FAILED, ts_negotfailed, respond,				(1 + 2 + (caddr_t)&hdr->_tpdufr.CRCC - (caddr_t)hdr) 					/* ^ more or less the location of class */				)			IFTRACE(D_CONN)				tptrace(TPPTmisc, 					"after 1 consist class, out, tpconsout",					tpcb->tp_class, dgout_routine, tpcons_output, 0					);			ENDTRACE			CHECK(				((class_to_use == TP_CLASS_0)&&					(dgout_routine != tpcons_output)),				E_TP_NEGOT_FAILED, ts_negotfailed, respond,				(1 + 2 + (caddr_t)&hdr->_tpdufr.CRCC - (caddr_t)hdr) 					/* ^ more or less the location of class */				)#ifdef TPCONS				if (tpcb->tp_netservice == ISO_CONS &&					class_to_use == TP_CLASS_0) {					struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;					struct pklcd *lcp = (struct pklcd *)isop->isop_chan;					lcp->lcd_flags &= ~X25_DG_CIRCUIT;				}#endif			}			if( ! tpcb->tp_use_checksum)				IncStat(ts_csum_off);			if(tpcb->tp_xpd_service)				IncStat(ts_use_txpd);			if(tpcb->tp_xtd_format)				IncStat(ts_xtd_fmt);			IFTRACE(D_CONN)				tptrace(TPPTmisc, "after CC class flags dusize CCclass",					tpcb->tp_class, tpcb->tp_flags, tpcb->tp_tpdusize, 					hdr->tpdu_CCclass);			ENDTRACE			/* if called or calling suffices appeared on the CC, 			 * they'd better jive with what's in the pcb			 */			if( fsufxlen ) {				CHECK( ((tpcb->tp_fsuffixlen != fsufxlen) ||					bcmp(fsufxloc, tpcb->tp_fsuffix, fsufxlen)),					E_TP_INV_PVAL,ts_inv_sufx, respond, 					(1+fsufxloc - (caddr_t)hdr))			}			if( lsufxlen ) {				CHECK( ((tpcb->tp_lsuffixlen != lsufxlen) ||					bcmp(lsufxloc, tpcb->tp_lsuffix, lsufxlen)),					E_TP_INV_PVAL,ts_inv_sufx, respond, 					(1+lsufxloc - (caddr_t)hdr))			}			e.ATTR(CC_TPDU).e_sref =  sref;			e.ATTR(CC_TPDU).e_cdt  =  hdr->tpdu_CCcdt;			takes_data = TRUE;			e.ev_number = CC_TPDU;			IncStat(ts_CC_rcvd);			break;		case DC_TPDU_type:			if (sref != tpcb->tp_fref)				printf("INPUT: inv sufx DCsref 0x%x, tp_fref 0x%x\n",					sref, tpcb->tp_fref);								CHECK( (sref != tpcb->tp_fref), 				E_TP_MISM_REFS, ts_inv_sufx, discard,				(1 + (caddr_t)&hdr->tpdu_DCsref - (caddr_t)hdr))					e.ev_number = DC_TPDU;			IncStat(ts_DC_rcvd);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -