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

📄 d1_pkt.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
		int alert_level = s->d1->alert_fragment[0];		int alert_descr = s->d1->alert_fragment[1];		s->d1->alert_fragment_len = 0;		if (s->msg_callback)			s->msg_callback(0, s->version, SSL3_RT_ALERT, 				s->d1->alert_fragment, 2, s, s->msg_callback_arg);		if (s->info_callback != NULL)			cb=s->info_callback;		else if (s->ctx->info_callback != NULL)			cb=s->ctx->info_callback;		if (cb != NULL)			{			j = (alert_level << 8) | alert_descr;			cb(s, SSL_CB_READ_ALERT, j);			}		if (alert_level == 1) /* warning */			{			s->s3->warn_alert = alert_descr;			if (alert_descr == SSL_AD_CLOSE_NOTIFY)				{				s->shutdown |= SSL_RECEIVED_SHUTDOWN;				return(0);				}#if 0            /* XXX: this is a possible improvement in the future */			/* now check if it's a missing record */			if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)				{				unsigned short seq;				unsigned int frag_off;				unsigned char *p = &(s->d1->alert_fragment[2]);				n2s(p, seq);				n2l3(p, frag_off);				dtls1_retransmit_message(s, seq, frag_off, &found);				if ( ! found  && SSL_in_init(s))					{					/* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */					/* requested a message not yet sent, 					   send an alert ourselves */					ssl3_send_alert(s,SSL3_AL_WARNING,						DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);					}				}#endif			}		else if (alert_level == 2) /* fatal */			{			char tmp[16];			s->rwstate=SSL_NOTHING;			s->s3->fatal_alert = alert_descr;			SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);			BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);			ERR_add_error_data(2,"SSL alert number ",tmp);			s->shutdown|=SSL_RECEIVED_SHUTDOWN;			SSL_CTX_remove_session(s->ctx,s->session);			return(0);			}		else			{			al=SSL_AD_ILLEGAL_PARAMETER;			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);			goto f_err;			}		goto start;		}	if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */		{		s->rwstate=SSL_NOTHING;		rr->length=0;		return(0);		}	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)        {        struct ccs_header_st ccs_hdr;		dtls1_get_ccs_header(rr->data, &ccs_hdr);		if ( ccs_hdr.seq == s->d1->handshake_read_seq)			{			/* 'Change Cipher Spec' is just a single byte, so we know			 * exactly what the record payload has to look like */			/* XDTLS: check that epoch is consistent */			if (	(rr->length != DTLS1_CCS_HEADER_LENGTH) || 				(rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))				{				i=SSL_AD_ILLEGAL_PARAMETER;				SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);				goto err;				}						rr->length=0;						if (s->msg_callback)				s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, 					rr->data, 1, s, s->msg_callback_arg);						s->s3->change_cipher_spec=1;			if (!ssl3_do_change_cipher_spec(s))				goto err;						/* do this whenever CCS is processed */			dtls1_reset_seq_numbers(s, SSL3_CC_READ);						/* handshake read seq is reset upon handshake completion */			s->d1->handshake_read_seq++;						goto start;			}		else			{			rr->length = 0;			goto start;			}		}	/* Unexpected handshake message (Client Hello, or protocol violation) */	if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && 		!s->in_handshake)		{		struct hm_header_st msg_hdr;				/* this may just be a stale retransmit */		dtls1_get_message_header(rr->data, &msg_hdr);		if( rr->epoch != s->d1->r_epoch)			{			rr->length = 0;			goto start;			}		if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))			{#if 0 /* worked only because C operator preferences are not as expected (and       * because this is not really needed for clients except for detecting       * protocol violations): */			s->state=SSL_ST_BEFORE|(s->server)				?SSL_ST_ACCEPT				:SSL_ST_CONNECT;#else			s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;#endif			s->new_session=1;			}		i=s->handshake_func(s);		if (i < 0) return(i);		if (i == 0)			{			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);			return(-1);			}		if (!(s->mode & SSL_MODE_AUTO_RETRY))			{			if (s->s3->rbuf.left == 0) /* no read-ahead left? */				{				BIO *bio;				/* In the case where we try to read application data,				 * but we trigger an SSL handshake, we return -1 with				 * the retry option set.  Otherwise renegotiation may				 * cause nasty problems in the blocking world */				s->rwstate=SSL_READING;				bio=SSL_get_rbio(s);				BIO_clear_retry_flags(bio);				BIO_set_retry_read(bio);				return(-1);				}			}		goto start;		}	switch (rr->type)		{	default:#ifndef OPENSSL_NO_TLS		/* TLS just ignores unknown message types */		if (s->version == TLS1_VERSION)			{			rr->length = 0;			goto start;			}#endif		al=SSL_AD_UNEXPECTED_MESSAGE;		SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);		goto f_err;	case SSL3_RT_CHANGE_CIPHER_SPEC:	case SSL3_RT_ALERT:	case SSL3_RT_HANDSHAKE:		/* we already handled all of these, with the possible exception		 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that		 * should not happen when type != rr->type */		al=SSL_AD_UNEXPECTED_MESSAGE;		SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR);		goto f_err;	case SSL3_RT_APPLICATION_DATA:		/* At this point, we were expecting handshake data,		 * but have application data.  If the library was		 * running inside ssl3_read() (i.e. in_read_app_data		 * is set) and it makes sense to read application data		 * at this point (session renegotiation not yet started),		 * we will indulge it.		 */		if (s->s3->in_read_app_data &&			(s->s3->total_renegotiations != 0) &&			((				(s->state & SSL_ST_CONNECT) &&				(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&				(s->state <= SSL3_ST_CR_SRVR_HELLO_A)				) || (					(s->state & SSL_ST_ACCEPT) &&					(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&					(s->state >= SSL3_ST_SR_CLNT_HELLO_A)					)				))			{			s->s3->in_read_app_data=2;			return(-1);			}		else			{			al=SSL_AD_UNEXPECTED_MESSAGE;			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);			goto f_err;			}		}	/* not reached */f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);err:	return(-1);	}intdtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)	{	unsigned int n,tot;	int i;	if (SSL_in_init(s) && !s->in_handshake)		{		i=s->handshake_func(s);		if (i < 0) return(i);		if (i == 0)			{			SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);			return -1;			}		}	tot = s->s3->wnum;	n = len - tot;	while( n)		{		/* dtls1_write_bytes sends one record at a time, sized according to 		 * the currently known MTU */		i = dtls1_write_bytes(s, type, buf_, len);		if (i <= 0) return i;				if ((i == (int)n) ||			(type == SSL3_RT_APPLICATION_DATA &&				(s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))			{			/* next chunk of data should get another prepended empty fragment			 * in ciphersuites with known-IV weakness: */			s->s3->empty_fragment_done = 0;			return tot+i;			}		tot += i;		n-=i;		}	return tot;	}	/* this only happens when a client hello is received and a handshake 	 * is started. */static inthave_handshake_fragment(SSL *s, int type, unsigned char *buf, 	int len, int peek)	{		if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0))		/* (partially) satisfy request from storage */		{		unsigned char *src = s->d1->handshake_fragment;		unsigned char *dst = buf;		unsigned int k,n;				/* peek == 0 */		n = 0;		while ((len > 0) && (s->d1->handshake_fragment_len > 0))			{			*dst++ = *src++;			len--; s->d1->handshake_fragment_len--;			n++;			}		/* move any remaining fragment bytes: */		for (k = 0; k < s->d1->handshake_fragment_len; k++)			s->d1->handshake_fragment[k] = *src++;		return n;		}		return 0;	}/* Call this to write data in records of type 'type' * It will return <= 0 if not all data has been sent or non-blocking IO. */int dtls1_write_bytes(SSL *s, int type, const void *buf_, int len)	{	const unsigned char *buf=buf_;	unsigned int tot,n,nw;	int i;	unsigned int mtu;	s->rwstate=SSL_NOTHING;	tot=s->s3->wnum;	n=(len-tot);	/* handshake layer figures out MTU for itself, but data records	 * are also sent through this interface, so need to figure out MTU */#if 0	mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_MTU, 0, NULL);	mtu += DTLS1_HM_HEADER_LENGTH;  /* HM already inserted */#endif	mtu = s->d1->mtu;	if (mtu > SSL3_RT_MAX_PLAIN_LENGTH)		mtu = SSL3_RT_MAX_PLAIN_LENGTH;	if (n > mtu)		nw=mtu;	else		nw=n;		i=do_dtls1_write(s, type, &(buf[tot]), nw, 0);	if (i <= 0)		{		s->s3->wnum=tot;		return i;		}	if ( (int)s->s3->wnum + i == len)		s->s3->wnum = 0;	else 		s->s3->wnum += i;	return tot + i;	}int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)	{	unsigned char *p,*pseq;	int i,mac_size,clear=0;	int prefix_len = 0;	SSL3_RECORD *wr;	SSL3_BUFFER *wb;	SSL_SESSION *sess;	int bs;	/* first check if there is a SSL3_BUFFER still being written	 * out.  This will happen with non blocking IO */	if (s->s3->wbuf.left != 0)		{		OPENSSL_assert(0); /* XDTLS:  want to see if we ever get here */		return(ssl3_write_pending(s,type,buf,len));		}	/* If we have an alert to send, lets send it */	if (s->s3->alert_dispatch)		{		i=s->method->ssl_dispatch_alert(s);		if (i <= 0)			return(i);		/* if it went, fall through and send more stuff */		}	if (len == 0 && !create_empty_fragment)		return 0;	wr= &(s->s3->wrec);	wb= &(s->s3->wbuf);	sess=s->session;	if (	(sess == NULL) ||		(s->enc_write_ctx == NULL) ||		(s->write_hash == NULL))		clear=1;	if (clear)		mac_size=0;	else		mac_size=EVP_MD_size(s->write_hash);	/* DTLS implements explicit IV, so no need for empty fragments */#if 0	/* 'create_empty_fragment' is true only when this function calls itself */	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done		&& SSL_version(s) != DTLS1_VERSION)		{		/* countermeasure against known-IV weakness in CBC ciphersuites		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 		 */		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)			{			/* recursive function call with 'create_empty_fragment' set;			 * this prepares and buffers the data for an empty fragment			 * (these 'prefix_len' bytes are sent out later			 * together with the actual payload) */			prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);			if (prefix_len <= 0)				goto err;			if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)				{				/* insufficient space */				SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);				goto err;				}			}				s->s3->empty_fragment_done = 1;		}

⌨️ 快捷键说明

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