src/Cedar/VLanWin32.c
// Start tracking of the routing table

Start tracking of the routing table
Start tracking of the routing table
void RouteTrackingStart(SESSION *s)
{
	VLAN *v;
	ROUTE_TRACKING *t;
	UINT if_id = 0;
	ROUTE_ENTRY *e;
	ROUTE_ENTRY *dns = NULL;
	ROUTE_ENTRY *route_to_real_server_global = NULL;
	char tmp[64];
	UINT exclude_if_id = 0;
	bool already_exists = false;
	bool already_exists_by_other_account = false;
	IP eight;
	if (s == NULL)
	{
		return;
	}
	v = (VLAN *)s->PacketAdapter->Param;
	if (v->RouteState != NULL)
	{
		return;
	}
	if_id = GetInstanceId(v->InstanceName);
	Debug("[InstanceId of %s] = 0x%x\n", v->InstanceName, if_id);
	if (MsIsVista())
	{
		exclude_if_id = if_id;
	}
	e = GetBestRouteEntryEx(&s->ServerIP, exclude_if_id);
	if (e == NULL)
	{
		Debug("Failed to get GetBestRouteEntry().\n");
		return;
	}
	IPToStr(tmp, sizeof(tmp), &e->GatewayIP);
	Debug("GetBestRouteEntry() Succeed. [Gateway: %s]\n", tmp);
	if (MsIsVista())
	{
		e->Metric = e->OldIfMetric;
	}
	if (AddRouteEntryEx(e, &already_exists) == false)
	{
		FreeRouteEntry(e);
		e = NULL;
	}
	Debug("already_exists: %u\n", already_exists);
	if (already_exists)
	{
		if (s->Cedar->Client != NULL && s->Account != NULL)
		{
			UINT i;
			ACCOUNT *a;
			for (i = 0;i < LIST_NUM(s->Cedar->Client->AccountList);i++)
			{
				a = LIST_DATA(s->Cedar->Client->AccountList, i);
				Lock(a->lock);
				{
					SESSION *sess = a->ClientSession;
					if (sess != NULL && sess != s)
					{
						VLAN *v = sess->PacketAdapter->Param;
						if (v != NULL)
						{
							ROUTE_TRACKING *tr = v->RouteState;
							if (tr != NULL && e != NULL)
							{
								if (Cmp(tr->RouteToServer, e, sizeof(ROUTE_ENTRY)) == 0)
								{
									already_exists_by_other_account = true;
								}
							}
						}
					}
				}
				Unlock(a->lock);
			}
		}
		if (already_exists_by_other_account)
		{
			Debug("already_exists_by_other_account = %u\n", already_exists_by_other_account);
			already_exists = false;
		}
	}
	if (IsZeroIP(&s->DefaultDns) == false)
	{
		if (IsMyIPAddress(&s->DefaultDns) == false)
		{
			dns = GetBestRouteEntryEx(&s->DefaultDns, exclude_if_id);
			if (dns == NULL)
			{
				Debug("Failed to get GetBestRouteEntry DNS.\n");
			}
			else
			{
				if (MsIsVista())
				{
					dns->Metric = dns->OldIfMetric;
					if (AddRouteEntry(dns) == false)
					{
						FreeRouteEntry(dns);
						dns = NULL;
					}
				}
			}
		}
	}
	if (s->IsAzureSession && IsZeroIP(&s->AzureRealServerGlobalIp) == false)
	{
		if (IsMyIPAddress(&s->AzureRealServerGlobalIp) == false)
		{
			route_to_real_server_global = GetBestRouteEntryEx(&s->AzureRealServerGlobalIp, exclude_if_id);
			if (route_to_real_server_global != NULL)
			{
				if (MsIsVista())
				{
					route_to_real_server_global->Metric = route_to_real_server_global->OldIfMetric;
				}
				if (AddRouteEntry(route_to_real_server_global) == false)
				{
					FreeRouteEntry(route_to_real_server_global);
					route_to_real_server_global = NULL;
				}
			}
		}
	}
	if (s->Cedar->Client != NULL && s->Account != NULL)
	{
		Lock(s->Account->lock);
	}
	t = ZeroMalloc(sizeof(ROUTE_TRACKING));
	v->RouteState = t;
	t->RouteToServerAlreadyExists = already_exists;
	t->RouteToServer = e;
	t->RouteToDefaultDns = dns;
	t->RouteToRealServerGlobal = route_to_real_server_global;
	t->VLanInterfaceId = if_id;
	t->NextTrackingTime = 0;
	t->DeletedDefaultGateway = NewQueue();
	t->OldDefaultGatewayMetric = 0x7fffffff;
	if (s->Cedar->Client != NULL && s->Account != NULL)
	{
		Unlock(s->Account->lock);
	}
	SetIP(&eight, 8, 8, 8, 8);
	t->RouteToEight = GetBestRouteEntryEx(&eight, exclude_if_id);
	GetDefaultDns(&t->OldDnsServer);
	if (IsNt())
	{
		char tmp[MAX_SIZE];
		MS_ADAPTER *a;
		Format(tmp, sizeof(tmp), VLAN_ADAPTER_NAME_TAG, v->InstanceName);
		a = MsGetAdapter(tmp);
		if (a != NULL)
		{
			if (a->UseDhcp)
			{
				bool ret = Win32ReleaseAddressByGuidEx(a->Guid, 100);
				Debug("*** Win32ReleaseAddressByGuidEx = %u\n", ret);
				ret = Win32RenewAddressByGuidEx(a->Guid, 100);
				Debug("*** Win32RenewAddressByGuidEx = %u\n", ret);
			}
			MsFreeAdapter(a);
		}
	}
	else
	{
		Win32RenewDhcp9x(if_id);
	}
	Win32FlushDnsCache();
	t->RouteChange = NewRouteChange();
	Debug("t->RouteChange = 0x%p\n", t->RouteChange);
}
void RouteTrackingStart ( SESSION * s ) { VLAN * v ; ROUTE_TRACKING * t ; UINT if_id = 0 ; ROUTE_ENTRY * e ; ROUTE_ENTRY * dns = NULL ; ROUTE_ENTRY * route_to_real_server_global = NULL ; char tmp [ 64 ] ; UINT exclude_if_id = 0 ; bool already_exists = false ; bool already_exists_by_other_account = false ; IP eight ; if ( s == NULL ) { return ; } v = ( VLAN * ) s -> PacketAdapter -> Param ; if ( v -> RouteState != NULL ) { return ; } if_id = GetInstanceId ( v -> InstanceName ) ; Debug ( " \n " , v -> InstanceName , if_id ) ; if ( MsIsVista ( ) ) { exclude_if_id = if_id ; } e = GetBestRouteEntryEx ( & s -> ServerIP , exclude_if_id ) ; if ( e == NULL ) { Debug ( " \n " ) ; return ; } IPToStr ( tmp , sizeof ( tmp ) , & e -> GatewayIP ) ; Debug ( " \n " , tmp ) ; if ( MsIsVista ( ) ) { e -> Metric = e -> OldIfMetric ; } if ( AddRouteEntryEx ( e , & already_exists ) == false ) { FreeRouteEntry ( e ) ; e = NULL ; } Debug ( " \n " , already_exists ) ; if ( already_exists ) { if ( s -> Cedar -> Client != NULL && s -> Account != NULL ) { UINT i ; ACCOUNT * a ; for ( i = 0 ; i < LIST_NUM ( s -> Cedar -> Client -> AccountList ) ; i ++ ) { a = LIST_DATA ( s -> Cedar -> Client -> AccountList , i ) ; Lock ( a -> lock ) ; { SESSION * sess = a -> ClientSession ; if ( sess != NULL && sess != s ) { VLAN * v = sess -> PacketAdapter -> Param ; if ( v != NULL ) { ROUTE_TRACKING * tr = v -> RouteState ; if ( tr != NULL && e != NULL ) { if ( Cmp ( tr -> RouteToServer , e , sizeof ( ROUTE_ENTRY ) ) == 0 ) { already_exists_by_other_account = true ; } } } } } Unlock ( a -> lock ) ; } } if ( already_exists_by_other_account ) { Debug ( " \n " , already_exists_by_other_account ) ; already_exists = false ; } } if ( IsZeroIP ( & s -> DefaultDns ) == false ) { if ( IsMyIPAddress ( & s -> DefaultDns ) == false ) { dns = GetBestRouteEntryEx ( & s -> DefaultDns , exclude_if_id ) ; if ( dns == NULL ) { Debug ( " \n " ) ; } else { if ( MsIsVista ( ) ) { dns -> Metric = dns -> OldIfMetric ; if ( AddRouteEntry ( dns ) == false ) { FreeRouteEntry ( dns ) ; dns = NULL ; } } } } } if ( s -> IsAzureSession && IsZeroIP ( & s -> AzureRealServerGlobalIp ) == false ) { if ( IsMyIPAddress ( & s -> AzureRealServerGlobalIp ) == false ) { route_to_real_server_global = GetBestRouteEntryEx ( & s -> AzureRealServerGlobalIp , exclude_if_id ) ; if ( route_to_real_server_global != NULL ) { if ( MsIsVista ( ) ) { route_to_real_server_global -> Metric = route_to_real_server_global -> OldIfMetric ; } if ( AddRouteEntry ( route_to_real_server_global ) == false ) { FreeRouteEntry ( route_to_real_server_global ) ; route_to_real_server_global = NULL ; } } } } if ( s -> Cedar -> Client != NULL && s -> Account != NULL ) { Lock ( s -> Account -> lock ) ; } t = ZeroMalloc ( sizeof ( ROUTE_TRACKING ) ) ; v -> RouteState = t ; t -> RouteToServerAlreadyExists = already_exists ; t -> RouteToServer = e ; t -> RouteToDefaultDns = dns ; t -> RouteToRealServerGlobal = route_to_real_server_global ; t -> VLanInterfaceId = if_id ; t -> NextTrackingTime = 0 ; t -> DeletedDefaultGateway = NewQueue ( ) ; t -> OldDefaultGatewayMetric = 0x7fffffff ; if ( s -> Cedar -> Client != NULL && s -> Account != NULL ) { Unlock ( s -> Account -> lock ) ; } SetIP ( & eight , 8 , 8 , 8 , 8 ) ; t -> RouteToEight = GetBestRouteEntryEx ( & eight , exclude_if_id ) ; GetDefaultDns ( & t -> OldDnsServer ) ; if ( IsNt ( ) ) { char tmp [ MAX_SIZE ] ; MS_ADAPTER * a ; Format ( tmp , sizeof ( tmp ) , VLAN_ADAPTER_NAME_TAG , v -> InstanceName ) ; a = MsGetAdapter ( tmp ) ; if ( a != NULL ) { if ( a -> UseDhcp ) { bool ret = Win32ReleaseAddressByGuidEx ( a -> Guid , 100 ) ; Debug ( " \n " , ret ) ; ret = Win32RenewAddressByGuidEx ( a -> Guid , 100 ) ; Debug ( " \n " , ret ) ; } MsFreeAdapter ( a ) ; } } else { Win32RenewDhcp9x ( if_id ) ; } Win32FlushDnsCache ( ) ; t -> RouteChange = NewRouteChange ( ) ; Debug ( " \n " , t -> RouteChange ) ; }
Start tracking of the routing table
Start tracking of the routing table
// Validate arguments
 // Get the interface ID of the virtual LAN card
 // The routing table by the virtual LAN card body should be
 // excluded explicitly in Windows Vista
 // Get the route to the server
 // Acquisition failure
 // Add a route
 // Get the routing table to the DNS server
 // (If the DNS server is this PC itself, there's no need to get)
 // Getting failure
 // Add a route
 // Add also a static route to the real server in the case of via VPN Azure
 // Initialize
 // Get the route to 8.8.8.8
 // Get the current default DNS server to detect network changes
 // Get as soon as releasing the IP address in the case of using DHCP
 // For Win9x
 // Clear the DNS cache
 // Detect a change in the routing table (for only supported OS)
