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

📄 demux.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
      EVENT_SA_REPLACE, aggr_inR1_outI2 },    /* STATE_AGGR_R1:     * SMF_PSK_AUTH: HDR*, HASH_I --> done     * SMF_DS_AUTH: HDR*, SIG_I   --> done     */    { STATE_AGGR_R1, STATE_AGGR_R2,      SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT      | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2,      P(HASH), P(VID) | P(NATD_RFC), PT(NONE),      EVENT_SA_REPLACE, aggr_inI2 },    /* STATE_AGGR_R1: HDR*, HASH_I --> done */    { STATE_AGGR_R1, STATE_AGGR_R2,      SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT      | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2,      P(SIG), P(VID) | P(NATD_RFC), PT(NONE),      EVENT_SA_REPLACE, aggr_inI2 },    /* STATE_AGGR_I2: can only get here due to packet loss */    { STATE_AGGR_I2, STATE_UNDEFINED,      SMF_ALL_AUTH | SMF_INITIATOR | SMF_RETRANSMIT_ON_DUPLICATE,      LEMPTY, LEMPTY, PT(NONE), EVENT_NULL, unexpected },    /* STATE_AGGR_R2: can only get here due to packet loss */    { STATE_AGGR_R2, STATE_UNDEFINED,      SMF_ALL_AUTH,      LEMPTY, LEMPTY, PT(NONE), EVENT_NULL, unexpected },    /***** Phase 2 Quick Mode *****/    /* No state for quick_outI1:     * --> HDR*, HASH(1), SA, Nr [, KE ] [, IDci, IDcr ]     */    /* STATE_QUICK_R0:     * HDR*, HASH(1), SA, Ni [, KE ] [, IDci, IDcr ] -->     * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ]     * Installs inbound IPsec SAs.     * Because it may suspend for asynchronous DNS, first_out_payload     * is set to NONE to suppress early emission of HDR*.     * ??? it is legal to have multiple SAs, but we don't support it yet.     */    { STATE_QUICK_R0, STATE_QUICK_R1    , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY#ifdef NAT_TRAVERSAL    , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(NONE)#else    , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID), PT(NONE)#endif    , EVENT_RETRANSMIT, quick_inI1_outR1 },    /* STATE_QUICK_I1:     * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ] -->     * HDR*, HASH(3)     * Installs inbound and outbound IPsec SAs, routing, etc.     * ??? it is legal to have multiple SAs, but we don't support it yet.     */    { STATE_QUICK_I1, STATE_QUICK_I2    , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_REPLY#ifdef NAT_TRAVERSAL    , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(HASH)#else    , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID), PT(HASH)#endif    , EVENT_SA_REPLACE, quick_inR1_outI2 },    /* STATE_QUICK_R1: HDR*, HASH(3) --> done     * Installs outbound IPsec SAs, routing, etc.     */    { STATE_QUICK_R1, STATE_QUICK_R2    , SMF_ALL_AUTH | SMF_ENCRYPTED    , P(HASH), LEMPTY, PT(NONE)    , EVENT_SA_REPLACE, quick_inI2 },    /* STATE_QUICK_I2: can only happen due to lost packet */    { STATE_QUICK_I2, STATE_UNDEFINED    , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE    , LEMPTY, LEMPTY, PT(NONE)    , EVENT_NULL, unexpected },    /* STATE_QUICK_R2: can only happen due to lost packet */    { STATE_QUICK_R2, STATE_UNDEFINED    , SMF_ALL_AUTH | SMF_ENCRYPTED    , LEMPTY, LEMPTY, PT(NONE)    , EVENT_NULL, unexpected },    /***** informational messages *****/    /* STATE_INFO: */    { STATE_INFO, STATE_UNDEFINED    , SMF_ALL_AUTH    , LEMPTY, LEMPTY, PT(NONE)    , EVENT_NULL, informational },    /* STATE_INFO_PROTECTED: */    { STATE_INFO_PROTECTED, STATE_UNDEFINED    , SMF_ALL_AUTH | SMF_ENCRYPTED    , P(HASH), LEMPTY, PT(NONE)    , EVENT_NULL, informational },#ifdef XAUTH    { STATE_XAUTH_R0, STATE_XAUTH_R1    , SMF_ALL_AUTH | SMF_ENCRYPTED     , P(ATTR) | P(HASH), P(VID), PT(NONE)    , EVENT_NULL, xauth_inR0 },  /*Re-transmit may be done by previous state*/    { STATE_XAUTH_R1, STATE_MAIN_R3    , SMF_ALL_AUTH | SMF_ENCRYPTED     , P(ATTR) | P(HASH), P(VID), PT(NONE)    , EVENT_SA_REPLACE, xauth_inR1 },#if 0    /* for situation where there is XAUTH + ModeCFG */    { STATE_XAUTH_R2, STATE_XAUTH_R3    , SMF_ALL_AUTH | SMF_ENCRYPTED     , P(ATTR) | P(HASH), P(VID), PT(NONE)    , EVENT_SA_REPLACE, xauth_inR2 },    { STATE_XAUTH_R3, STATE_MAIN_R3    , SMF_ALL_AUTH | SMF_ENCRYPTED     , P(ATTR) | P(HASH), P(VID), PT(NONE)    , EVENT_SA_REPLACE, xauth_inR3 },#endif#endif#ifdef MODECFG/* MODE_CFG_x: * Case R0:  Responder	->	Initiator *			<-	Req(addr=0) *	    Reply(ad=x)	-> *	     * Case R1: Set(addr=x)	-> *			<-	Ack(ok) */    { STATE_MODE_CFG_R0, STATE_MODE_CFG_R1    , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY    , P(ATTR) | P(HASH), P(VID), PT(HASH)    , EVENT_SA_REPLACE, modecfg_inR0 },    { STATE_MODE_CFG_R1, STATE_MODE_CFG_R2    , SMF_ALL_AUTH | SMF_ENCRYPTED    , P(ATTR) | P(HASH), P(VID), PT(HASH)    , EVENT_SA_REPLACE, modecfg_inR1 },    { STATE_MODE_CFG_R2, STATE_UNDEFINED    , SMF_ALL_AUTH | SMF_ENCRYPTED    , LEMPTY, LEMPTY, PT(NONE)    , EVENT_NULL, unexpected },    { STATE_MODE_CFG_I1, STATE_MAIN_I4    , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2    , P(ATTR) | P(HASH), P(VID), PT(HASH)    , EVENT_SA_REPLACE, modecfg_inR1 },#endif#ifdef XAUTH    { STATE_XAUTH_I0, STATE_XAUTH_I1    , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2    , P(ATTR) | P(HASH), P(VID), PT(HASH)    , EVENT_SA_REPLACE, xauth_inI0 },    { STATE_XAUTH_I1, STATE_MAIN_I4    , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2    , P(ATTR) | P(HASH), P(VID), PT(HASH)    , EVENT_SA_REPLACE, xauth_inI1 },#endif#undef P#undef PT};voidinit_demux(void){    /* fill ike_microcode_index:     * make ike_microcode_index[s] point to first entry in     * state_microcode_table for state s (backward scan makes this easier).     * Check that table is in order -- catch coding errors.     * For what it's worth, this routine is idempotent.     */    const struct state_microcode *t;    for (t = &state_microcode_table[elemsof(state_microcode_table) - 1];;)    {	passert(STATE_IKE_FLOOR <= t->state && t->state < STATE_IKE_ROOF);	ike_microcode_index[t->state - STATE_IKE_FLOOR] = t;	if (t == state_microcode_table)	    break;	t--;	passert(t[0].state <= t[1].state);    }}/* Process any message on the MSG_ERRQUEUE * * This information is generated because of the IP_RECVERR socket option. * The API is sparsely documented, and may be LINUX-only, and only on * fairly recent versions at that (hence the conditional compilation). * * - ip(7) describes IP_RECVERR * - recvmsg(2) describes MSG_ERRQUEUE * - readv(2) describes iovec * - cmsg(3) describes how to process auxilliary messages * * ??? we should link this message with one we've sent * so that the diagnostic can refer to that negotiation. * * ??? how long can the messge be? * * ??? poll(2) has a very incomplete description of the POLL* events. * We assume that POLLIN, POLLOUT, and POLLERR are all we need to deal with * and that POLLERR will be on iff there is a MSG_ERRQUEUE message. * * We have to code around a couple of surprises: * * - Select can say that a socket is ready to read from, and *   yet a read will hang.  It turns out that a message available on the *   MSG_ERRQUEUE will cause select to say something is pending, but *   a normal read will hang.  poll(2) can tell when a MSG_ERRQUEUE *   message is pending. * *   This is dealt with by calling check_msg_errqueue after select *   has indicated that there is something to read, but before the *   read is performed.  check_msg_errqueue will return TRUE if there *   is something left to read. * * - A write to a socket may fail because there is a pending MSG_ERRQUEUE *   message, without there being anything wrong with the write.  This *   makes for confusing diagnostics. * *   To avoid this, we call check_msg_errqueue before a write.  True, *   there is a race condition (a MSG_ERRQUEUE message might arrive *   between the check and the write), but we should eliminate many *   of the problematic events.  To narrow the window, the poll(2) *   will await until an event happens (in the case or a write, *   POLLOUT; this should be benign for POLLIN). */#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)static boolcheck_msg_errqueue(const struct iface *ifp, short interest){    struct pollfd pfd;    pfd.fd = ifp->fd;    pfd.events = interest | POLLPRI | POLLOUT;    while (pfd.revents = 0    , poll(&pfd, 1, -1) > 0 && (pfd.revents & POLLERR))    {	u_int8_t buffer[3000];	/* hope that this is big enough */	union	{	    struct sockaddr sa;	    struct sockaddr_in sa_in4;	    struct sockaddr_in6 sa_in6;	} from;	int from_len = sizeof(from);	int packet_len;	struct msghdr emh;	struct iovec eiov;	union {	    /* force alignment (not documented as necessary) */	    struct cmsghdr ecms;	    /* how much space is enough? */	    unsigned char space[256];	} ecms_buf;	struct cmsghdr *cm;	char fromstr[sizeof(" for message to  port 65536") + INET6_ADDRSTRLEN];	struct state *sender = NULL;	zero(&from.sa);	from_len = sizeof(from);	emh.msg_name = &from.sa;	/* ??? filled in? */	emh.msg_namelen = sizeof(from);	emh.msg_iov = &eiov;	emh.msg_iovlen = 1;	emh.msg_control = &ecms_buf;	emh.msg_controllen = sizeof(ecms_buf);	emh.msg_flags = 0;	eiov.iov_base = buffer;	/* see readv(2) */	eiov.iov_len = sizeof(buffer);	packet_len = recvmsg(ifp->fd, &emh, MSG_ERRQUEUE);	if (packet_len == -1)	{	    log_errno((e, "recvmsg(,, MSG_ERRQUEUE) on %s failed in comm_handle"		, ifp->rname));	    break;	}	else if (packet_len == sizeof(buffer))	{	    openswan_log("MSG_ERRQUEUE message longer than %lu bytes; truncated"		, (unsigned long) sizeof(buffer));	}	else	{	    sender = find_sender((size_t) packet_len, buffer);	}	DBG_cond_dump(DBG_ALL, "rejected packet:\n", buffer, packet_len);	DBG_cond_dump(DBG_ALL, "control:\n", emh.msg_control, emh.msg_controllen);	/* ??? Andi Kleen <ak@suse.de> and misc documentation	 * suggests that name will have the original destination	 * of the packet.  We seem to see msg_namelen == 0.	 * Andi says that this is a kernel bug and has fixed it.	 * Perhaps in 2.2.18/2.4.0.	 */	passert(emh.msg_name == &from.sa);	DBG_cond_dump(DBG_ALL, "name:\n", emh.msg_name	    , emh.msg_namelen);	fromstr[0] = '\0';	/* usual case :-( */	switch (from.sa.sa_family)	{	char as[INET6_ADDRSTRLEN];	case AF_INET:	    if (emh.msg_namelen == sizeof(struct sockaddr_in))		snprintf(fromstr, sizeof(fromstr)		, " for message to %s port %u"		    , inet_ntop(from.sa.sa_family		    , &from.sa_in4.sin_addr, as, sizeof(as))		    , ntohs(from.sa_in4.sin_port));	    break;	case AF_INET6:	    if (emh.msg_namelen == sizeof(struct sockaddr_in6))		snprintf(fromstr, sizeof(fromstr)		    , " for message to %s port %u"		    , inet_ntop(from.sa.sa_family		    , &from.sa_in6.sin6_addr, as, sizeof(as))		    , ntohs(from.sa_in6.sin6_port));	    break;	}	for (cm = CMSG_FIRSTHDR(&emh)	; cm != NULL	; cm = CMSG_NXTHDR(&emh,cm))	{	    if (cm->cmsg_level == SOL_IP	    && cm->cmsg_type == IP_RECVERR)	    {		/* ip(7) and recvmsg(2) specify:		 * ee_origin is SO_EE_ORIGIN_ICMP for ICMP		 *  or SO_EE_ORIGIN_LOCAL for locally generated errors.		 * ee_type and ee_code are from the ICMP header.		 * ee_info is the discovered MTU for EMSGSIZE errors		 * ee_data is not used.		 *		 * ??? recvmsg(2) says "SOCK_EE_OFFENDER" but		 * means "SO_EE_OFFENDER".  The OFFENDER is really		 * the router that complained.  As such, the port		 * is meaningless.		 */		/* ??? cmsg(3) claims that CMSG_DATA returns		 * void *, but RFC 2292 and /usr/include/bits/socket.h		 * say unsigned char *.  The manual is being fixed.		 */		struct sock_extended_err *ee = (void *)CMSG_DATA(cm);		const char *offstr = "unspecified";		char offstrspace[INET6_ADDRSTRLEN];		char orname[50];		if (cm->cmsg_len > CMSG_LEN(sizeof(struct sock_extended_err)))		{		    const struct sockaddr *offender = SO_EE_OFFENDER(ee);		    switch (offender->sa_family)		    {		    case AF_INET:			offstr = inet_ntop(offender->sa_family			    , &((const struct sockaddr_in *)offender)->sin_addr			    , offstrspace, sizeof(offstrspace));			break;		    case AF_INET6:			offstr = inet_ntop(offender->sa_family			    , &((const struct sockaddr_in6 *)offender)->sin6_addr			    , offstrspace, sizeof(offstrspace));			break;		    default:			offstr = "unknown";			break;		    }		}		switch (ee->ee_origin)		{		case SO_EE_ORIGIN_NONE:		    snprintf(orname, sizeof(orname), "none");		    break;		case SO_EE_ORIGIN_LOCAL:		    snprintf(orname, sizeof(orname), "local");		    break;		case SO_EE_ORIGIN_ICMP:		    snprintf(orname, sizeof(orname)			, "ICMP type %d code %d (not authenticated)"			, ee->ee_type, ee->ee_code			);		    break;		case SO_EE_ORIGIN_ICMP6:		    snprintf(orname, sizeof(orname)			, "ICMP6 type %d code %d (not authenticated)"			, ee->ee_type, ee->ee_code			);		    break;		default:		    snprintf(orname, sizeof(orname), "invalid origin %lu"			, (unsigned long) ee->ee_origin);		    break;		}		{		    struct state *old_state = cur_state;		    cur_state = sender;		    /* note dirty trick to suppress ~ at start of format		     * if we know what state to blame.

⌨️ 快捷键说明

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