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

📄 radius_tx.c

📁 vxworks下radius协议栈 的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		  {			/* allocate new packet identifier */			if (radius_get_next_available_packet_identifier_per_server (p_server, &p_server->packet_identifier_count) == FAIL)			  {				/* skip this one, wait for the next timer */				*ep_error_packet_id = false; 				radius_printf (RADIUS_ALARM_PRINTF,"RADIUS Retransmission: Failed to get next available packet identifier.\r\n");				return;			  }			/* initialize this packet id's reused timer before freeing it to avoid using it right away.  If the response for this 			packet id arrived, we could be mistaken for the new request */			radius_set_packet_id_reused_timer_before_reuse_per_server (p_server, sptr_packet->header.identifier);			/* update packet identifier in local structures */			sptr_packet->header.identifier = (BYTE) (p_server->packet_identifier_count);			sptr_request_entry->packet_header.identifier = (BYTE) (p_server->packet_identifier_count);						/* Update attribute in the packet */			bp_value = &sptr_attribute_entry_in_packet->value[0];			delay_time = deserialize_ulong (&bp_value);			delay_time += retransmission_interval;			bp_value = &sptr_attribute_entry_in_packet->value[0];			serialize_ulong (delay_time, &bp_value); 						/* encrpt the modified packet */			memset (&sptr_packet->header.authenticator[0], 0, RADIUS_SIZE_OF_AUTHENTICATOR);			if (radius_accounting_fill_in_request_authenticator (sptr_packet, total_packet_length, p_server, (BYTE *)&sptr_packet->header.authenticator[0]) == false)			  {				/* skip this one, wait for the next timer */				*ep_error_packet_id = false;				radius_printf (RADIUS_ALARM_PRINTF,"RADIUS Retransmission: radius_accounting_fill_in_request_authenticator() failed\n");				return;			  }						radius_printf (RADIUS_DATA_PRINTF,"RADIUS Retransmission: Updated Delay_time to %d and ID to %d.\r\n", delay_time, 						sptr_packet->header.identifier);			return;		  }		attribute_length = (UINT) sptr_attribute_entry_in_packet->length;				packet_length -= attribute_length;				sptr_attribute_entry_in_packet = (RADIUS_ATTRIBUTE_ENTRY_IN_PACKET *) ((UINT) sptr_attribute_entry_in_packet + attribute_length);		}	return;}/******************************************************************************************Function:	resend_radius_packetDescription:	Resend the RADIUS request packet after the retransmission interval expires.				However, if the max_retransmit_count has been exceeded, it will search for				the next available server of the right type (authentication or accounting).				If the search is found, it resends the packet to the new server. Otherwise,				it sends an error message back to the requester.******************************************************************************************/enum TEST resend_radius_packet (RADIUS_REQUEST_ENTRY *sptr_request_entry){	RADIUS_PACKET *sptr_packet;	RADIUS_SERVER *p_server, *p_server_tmp;	RW_CONTAINER_ITERATOR server_iterator, server_iterator_tmp;	bool packet_id_availability, next_server_available = false;	struct in_addr	inetAddr;	BYTE	ip_string[18];	ULONG	value;		/* These 2 lines are just to get rid of compiler warnings */	p_server_tmp = NULL;	server_iterator_tmp = (RW_CONTAINER_ITERATOR)NULL; 		packet_id_availability = true;	if (sptr_request_entry->backup_server == true)		{		server_iterator = (RW_CONTAINER_ITERATOR) sptr_request_entry->backup_server_handle;		}	else		{		server_iterator = (RW_CONTAINER_ITERATOR) sptr_request_entry->server_handle;		}	p_server = (RADIUS_SERVER*) rw_container_at (server_iterator);	sptr_packet = sptr_request_entry->sptr_packet;	++sptr_request_entry->request_retry_count;	if (sptr_request_entry->request_retry_count > p_server->max_retransmit_count)		{		radius_printf(RADIUS_TRACE_PRINTF, "Retry count expires\n");		/* set reused timer just incase we don't use this packet id right away which might cause corrupted response */		radius_set_packet_id_reused_timer_before_reuse_per_server (p_server, sptr_packet->header.identifier);		/* check if another RADIUS server is available */		if (sptr_request_entry->any_server == true && 			(sptr_request_entry->backup_server_handle = radius_get_next_server(server_iterator, p_server->type)) != INVALID_HANDLE)		    {	/* yes, another RADIUS server is available */		    		    	/* update the info in current RADIUS_REQUEST_ENTRY structure */			radius_printf(RADIUS_TRACE_PRINTF, "Found a back-up server, server handle = 0x%x\n",					sptr_request_entry->backup_server_handle);			sptr_request_entry->request_time = 0;			sptr_request_entry->request_retry_count = 0;						/* the rest of the info should stay the same, now save this RADIUS server temporarily */			server_iterator_tmp = (RW_CONTAINER_ITERATOR) sptr_request_entry->backup_server_handle;			p_server_tmp = (RADIUS_SERVER*) rw_container_at (server_iterator_tmp);			next_server_available = true;			/* update pending request and statistics for the back-up server */			++p_server_tmp->pending_request_count;#ifdef __RADIUS_MIB__			semTake (g_sem_radius_mib, WAIT_FOREVER);#endif			switch (sptr_request_entry->packet_header.code)				{				case RADIUS_ACCESS_REQUEST:					++p_server_tmp->statistics.authentication_access_requests_tx;					++p_server_tmp->statistics.authentication_pending_access_requests;								break;				case RADIUS_ACCOUNTING_REQUEST:					++p_server_tmp->statistics.accounting_requests_tx;					++p_server_tmp->statistics.accounting_pending_access_requests;					break;				default:					/* should not happen! */					break;				}#ifdef __RADIUS_MIB__			semGive (g_sem_radius_mib);#endif			/* decrement pending request count on current server as the request is now			   handled by another server			*/			--p_server->pending_request_count;		    }		else	/* there is no more RADIUS server available, send error msg to requester */		    {			radius_printf(RADIUS_TRACE_PRINTF, "No more server available\n");			rwos_mutex_release (rwos_radius_data_mutex);		    (*sptr_request_entry->p_callbacks->fptr_radius_error_callback) (sptr_request_entry->request_handle, RADIUS_RETRY_LIMIT_REACHED);			rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER);			--p_server->pending_request_count;			radius_printf(RADIUS_TRACE_PRINTF, 				"Pending request count = %d\n", p_server->pending_request_count);			next_server_available = false;			}				/* tk: check if there has been a call to destroy the server.  Delete the server only		if there is no pending request on the server and there is no pending client who		still owns (i.e. has not freed) all the copies of the server handle.		*/  		if ((p_server->deleted == true) && 			(p_server->pending_request_count == 0) &&			(p_server->user_count == 0))			{			radius_printf(RADIUS_TRACE_PRINTF, "Resend done: Server deleted\n");			rw_container_remove (server_iterator);			if (p_server->bp_secret != NULL)				{					table_free (p_server->bp_secret);				}			table_free (p_server);			}		/* free copy of target server handle or the back-up server handle */		rw_container_free_iterator (server_iterator);#ifdef __RADIUS_MIB__		semTake (g_sem_radius_mib, WAIT_FOREVER);#endif		switch (sptr_request_entry->packet_header.code)			{			case RADIUS_ACCESS_REQUEST:				--p_server->statistics.authentication_pending_access_requests;							break;			case RADIUS_ACCOUNTING_REQUEST:				--p_server->statistics.accounting_pending_access_requests;				break;			default:				/* should not happen! */				break;			}#ifdef __RADIUS_MIB__		semGive (g_sem_radius_mib);#endif		if (next_server_available == true)			{			p_server = p_server_tmp;	 /* set p_server to the new Radius server */			server_iterator = server_iterator_tmp;			sptr_request_entry->backup_server = true;			/* display IP address of next server */			radius_util_serialize_ulong(p_server->ip_address, (BYTE *)&value);			inetAddr.s_addr = value; 			inet_ntoa_b(inetAddr, ip_string);			radius_printf(RADIUS_DATA_PRINTF, "Sending to another server %s\n", ip_string);			}		else			{			return (FAIL);			}		}	if (sptr_request_entry->packet_header.code == RADIUS_ACCOUNTING_REQUEST)		{		update_delay_time_for_retransmission (sptr_packet, sptr_request_entry, p_server->retransmission_interval, p_server, &packet_id_availability);        if (packet_id_availability == false)			{			return (PASS); /* wait for the next timer */			}		}			sptr_request_entry->request_timestamp = rwos_get_system_elapsed_time ();	radius_printf(RADIUS_TRACE_PRINTF, "Resending request ...\n");			if (send_radius_udp_packet (sptr_packet, sptr_request_entry->packet_header.code, sptr_request_entry->packet_header.length, 		p_server) == FAIL)		{			/* free packet id right away and need not wait for reused timer because we are unable to send */		radius_free_packet_identifier_per_server (p_server, sptr_request_entry->packet_header.identifier);		rwos_mutex_release (rwos_radius_data_mutex);		(*sptr_request_entry->p_callbacks->fptr_radius_error_callback) (sptr_request_entry->request_handle, RADIUS_UDP_SEND_ERROR);				rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER);		--p_server->pending_request_count;#ifdef __RADIUS_MIB__		semTake (g_sem_radius_mib, WAIT_FOREVER);#endif		switch (sptr_request_entry->packet_header.code)			{			case RADIUS_ACCESS_REQUEST:				--p_server->statistics.authentication_pending_access_requests;							break;			case RADIUS_ACCOUNTING_REQUEST:				--p_server->statistics.accounting_pending_access_requests;				break;			default:				/* should not happen! */				break;			}#ifdef __RADIUS_MIB__		semGive (g_sem_radius_mib);#endif		/* tk: check if there has been a call to destroy the server.  Delete the server only		if there is no pending request on the server and there is no pending client who		still owns (i.e. has not freed) all the copies of the server handle.		*/ 		if ((p_server->deleted == true) && 			(p_server->pending_request_count == 0) &&			(p_server->user_count == 0))			{			radius_printf(RADIUS_TRACE_PRINTF, "Resend failed: Server deleted\n");			if (p_server->bp_secret != NULL)				{					table_free (p_server->bp_secret);				}			table_free (p_server);			rw_container_remove (server_iterator);	/* free the p_node */			}		/* free copy of target server handle or the back-up server handle */		rw_container_free_iterator (server_iterator);		return (FAIL);		}#ifdef __RADIUS_MIB__	semTake (g_sem_radius_mib, WAIT_FOREVER);#endif			switch (sptr_request_entry->packet_header.code)		{		case RADIUS_ACCESS_REQUEST:			++p_server->statistics.authentication_access_requests_retransmit;					break;		case RADIUS_ACCOUNTING_REQUEST:			++p_server->statistics.accounting_requests_retransmit;			break;		default:			/* should not happen! */			break;		}#ifdef __RADIUS_MIB__	semGive (g_sem_radius_mib);#endif			return (PASS);}/************************************************************************/static enum TEST send_radius_udp_packet (RADIUS_PACKET *sptr_packet, enum RADIUS_CODE code, UINT length, RADIUS_SERVER* p_server){	struct sockaddr_in remote_sockaddr_in;	int socket_descriptor;	print_radius_packet_header ("send_radius_udp_packet", &sptr_packet->header);		switch (code)		{		case RADIUS_ACCESS_REQUEST:			socket_descriptor = radius.authentication_socket_object.socket_descriptor;					break;		case RADIUS_ACCOUNTING_REQUEST:			socket_descriptor = radius.accounting_socket_object.socket_descriptor;			break;		default:			radius_printf (RADIUS_ALARM_PRINTF,"RADIUS: send_radius_udp_packet: Illegal packet type to send - %d\r\n", code);						return (FAIL);		}		remote_sockaddr_in.sin_family = AF_INET;	remote_sockaddr_in.sin_addr.s_addr = htonl (p_server->ip_address);	remote_sockaddr_in.sin_port = htons ((USHORT) p_server->port);	if ((socket_descriptor == 0) || (remote_sockaddr_in.sin_port == 0x0000) || 		(remote_sockaddr_in.sin_addr.s_addr == 0x00000000L))		{		radius_printf (RADIUS_SOCKET_PRINTF, "RADIUS: send_radius_udp_packet: illegal parameter\n");				return (FAIL);		}#ifdef VIRTUAL_STACK	virtualStackNumTaskIdSet (0);#endif	rwos_mutex_release (rwos_radius_data_mutex);	if (sendto (socket_descriptor, (caddr_t) sptr_packet, (int) length, (int) NULL, (SOCKADDR *) &remote_sockaddr_in, 		sizeof (SOCKADDR)) == ERROR)		{		if (errnoGet() == OUT_OF_MBUF)			{			radius_printf (RADIUS_SOCKET_PRINTF, "RADIUS: Network buffer depleted.\n");			rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER);			return (FAIL);			}		else			{			radius_printf (RADIUS_SOCKET_PRINTF, "RADIUS: send_radius_udp_packet: FAILED\n");			rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER);			return (FAIL);			}		}	rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER);	return (PASS);}

⌨️ 快捷键说明

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