当前位置:网站首页>Remove the influence of firewall and virtual machine on live555 startup IP address

Remove the influence of firewall and virtual machine on live555 startup IP address

2022-06-23 06:15:00 qianbo_ insist

live555 start-up IP Access method

live555 Of ip The acquisition method is different from other software , The main reason is that it is obtained through multicast . The code is as follows :

Boolean loopbackWorks = 1;

netAddressBits ourIPAddress(UsageEnvironment& env) {
    
  static netAddressBits ourAddress = 0;
  int sock = -1;
  struct in_addr testAddr;

  if (ReceivingInterfaceAddr != INADDR_ANY) {
    
    // Hack: If we were told to receive on a specific interface address, then 
    // define this to be our ip address:
    ourAddress = ReceivingInterfaceAddr;
  }

  if (ourAddress == 0) {
    
    // We need to find our source address
    struct sockaddr_in fromAddr;
    fromAddr.sin_addr.s_addr = 0;

    // Get our address by sending a (0-TTL) multicast packet,
    // receiving it, and looking at the source address used.
    // (This is kinda bogus, but it provides the best guarantee
    // that other nodes will think our address is the same as we do.)
    do {
    
      loopbackWorks = 0; // until we learn otherwise

      testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary
      Port testPort(15947); // ditto

      sock = setupDatagramSocket(env, testPort);
      if (sock < 0) break;

      if (!socketJoinGroup(env, sock, testAddr.s_addr)) break;

      unsigned char testString[] = "hostIdTest";
      unsigned testStringLength = sizeof testString;

      if (!writeSocket(env, sock, testAddr, testPort.num(), 0,
		       testString, testStringLength)) break;

      // Block until the socket is readable (with a 5-second timeout):
      fd_set rd_set;
      FD_ZERO(&rd_set);
      FD_SET((unsigned)sock, &rd_set);
      const unsigned numFds = sock+1;
      struct timeval timeout;
      timeout.tv_sec = 5;
      timeout.tv_usec = 0;
      int result = select(numFds, &rd_set, NULL, NULL, &timeout);
      if (result <= 0) break;

      unsigned char readBuffer[20];
      int bytesRead = readSocket(env, sock,
				 readBuffer, sizeof readBuffer,
				 fromAddr);
      if (bytesRead != (int)testStringLength
	  || strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) {
    
	break;
      }

      // We use this packet's source address, if it's good:
      loopbackWorks = !badAddressForUs(fromAddr.sin_addr.s_addr);
    } while (0);

    if (sock >= 0) {
    
      socketLeaveGroup(env, sock, testAddr.s_addr);
      closeSocket(sock);
    }

    if (!loopbackWorks) do {
    
      // We couldn't find our address using multicast loopback,
      // so try instead to look it up directly - by first getting our host name, and then resolving this host name
      char hostname[100];
      hostname[0] = '\0';
      int result = gethostname(hostname, sizeof hostname);
      if (result != 0 || hostname[0] == '\0') {
    
	env.setResultErrMsg("initial gethostname() failed");
	break;
      }

      // Try to resolve "hostname" to an IP address:
      NetAddressList addresses(hostname);
      NetAddressList::Iterator iter(addresses);
      NetAddress const* address;

      // Take the first address that's not bad:
      netAddressBits addr = 0;
      while ((address = iter.nextAddress()) != NULL) {
    
	netAddressBits a = *(netAddressBits*)(address->data());
	if (!badAddressForUs(a)) {
    
	  addr = a;
	  break;
	}
      }

      // Assign the address that we found to "fromAddr" (as if the 'loopback' method had worked), to simplify the code below: 
      fromAddr.sin_addr.s_addr = addr;
    } while (0);

    // Make sure we have a good address:
    netAddressBits from = fromAddr.sin_addr.s_addr;
    if (badAddressForUs(from)) {
    
      char tmp[100];
      sprintf(tmp, "This computer has an invalid IP address: %s", AddressString(from).val());
      env.setResultMsg(tmp);
      from = 0;
    }

    ourAddress = from;

    // Use our newly-discovered IP address, and the current time,
    // to initialize the random number generator's seed:
    struct timeval timeNow;
    gettimeofday(&timeNow, NULL);
    unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec;
    our_srandom(seed);
  }
  return ourAddress;
}

Two questions

     1、 The code itself is not a problem , First, the firewall problem , If the firewall cannot release some ports , You can't get IP Of , This leads directly to the final IP The address is the initial value "0.0.0.0", There's another problem , It is caused by virtual machines IP Address address problem .

     2、 When we install the virtual machine , There will be a lot more IP Address , This leads to a problem , Is that he will get a useless IP Address , These two problems need to be solved .

      Directly modifying live555 Acquisition IP The place of , Adding a configuration file is the most appropriate . Let's write a program to read the file config Things about documents

#pragma once
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm> //transform
#include <map>
#pragma comment(lib,"ws2_32")
#define GET_lower(x) transform(x.begin(), x.end(), x.begin(), ::tolower)
//to translate the string to upper 
#define Get_upper(x) transform(s.begin(), s.end(), s.begin(), ::toupper)

static void trim(std::string &s)
{
    
	if (s.empty())
		return;
	s.erase(s.find_last_not_of('\r') + 1); //the linux system getline must remove the '\r'
	s.erase(s.find_last_not_of(' ') + 1);
	//s.erase(s.find_last_not_of('\t') + 1);
	s.erase(0, s.find_first_not_of(' '));
	//s.erase(0, s.find_first_not_of('\t'));

}
static bool ifnote(const std::string & tmp)
{
    
	if (tmp.empty())
		return false;
	int l = (int)tmp.length();
	char a = tmp[0];
	char b;
	if (l >= 2)
		b = tmp[1];
	if (l == 1)
		return a == '#';
	if (l >= 2)
		return a == '#' || (a == '/'&& b == '/');
	return false;
}


//judge is node
//[] is the node, 
//len the line's length 
//if tmp is a node, the variable node return the real node name 
//the tmp string has been trimed trim
static bool ifnode(const std::string & tmp, std::string &node)
{
    
	int len = -1;
	node.clear();
	if (tmp.empty())
		return false;
	//trim(tmp);
	int l = (int)tmp.size();
	if (l > 2)//bigger than []
	{
    
		//cout<<"string:"<<tmp<<" "<<l<<endl;
		int take = 2;
		char a = tmp[0];
		char b = tmp[l - 1];
		if (b == '\r') //compatible with linux linux getline with '\r',but we have removed by trim function
		{
    
			b = tmp[l - 2];
			take = 3;// dec the '\r'
		}
		if (a == '[' && b == ']')
		{
    
			len = l - take;
			node = tmp.substr(1, len);
			return true;
		}
	}
	return false;
}
//static int get_key_value(std::string nodename, std::string & key, std::string & value)
//{
    
//
// GET_lower(nodename);
// GET_lower(key);
// //GET_lower(value);
// return splitnv(nodename, key, value);
// 
//
//}
//ini file key = value , analyse out key and value
static int splitnv(const std::string& source, std::string& key, std::string& value)
{
    

	if (source.empty())
		return -1;
	int pos = 0;
	int len = (int)source.length();
	//printf("the len is %d\n", len);
	for (pos = 0; pos < len; pos++)
	{
    
		if (source[pos] == '=')
			break;
	}
	if (pos == len - 1)
		return -1;
	//printf("the pos is %d\n", pos);
	key = source.substr(0, pos);
	value = source.substr(pos + 1);
	trim(key);
	trim(value);
	return 0;
}


static bool load_conf_file(const char *filename, std::string node_in, std::map<std::string, std::string> &ret)
{
    
	//std::ifstream myfile("./config.txt");
	if ((_access(filename, 0)) == -1)
	{
    
		printf_s("File not exists.\n");
		return false;
	}
	if (filename == NULL)
		filename = "config.txt";
	std::ifstream myfile(filename);
	std::string temp, node, nodename;
	if (!myfile.is_open())
	{
    
		std::cout << "can not open config.txt" << std::endl;
		return false;
	}
	std::cout << "load config file-->" << filename << std::endl;

	while (getline(myfile, temp))
	{
    
		trim(temp);
		if (!ifnote(temp)) //if is the node
		{
    
			std::string key, value;
			bool isnode = ifnode(temp, node);
			if (isnode)
				nodename = node;//
			else
			{
    
				if (node_in.compare(nodename) == 0)
				{
    
					if (splitnv(temp, key, value) == 0)
						ret[key] = value;
				}
			}
		}
	}
	myfile.close();
	return 0;
}

The configuration file

The configuration file is written as a node
[ipport]
ip=192.168.1.11
port= 8080

#include "node_config.h"
netAddressBits ourIPAddress() 
{
    
	std::map<std::string, std::string> ret;
	if(load_conf_file("config2.txt", "ipport", ret) == true)
	{
    
		std::cout << "ret size is " << ret.size() << std::endl;
		std::cout << ret["ip"] << std::endl;
		std::cout << ret["port"] << std::endl;
		return inet_addr(ret["ip"].c_str());
	}
	..... The following uses the original live555 Code for 
	
}

int main()
{
    
	std::cout<<ourIPAddress()<<std::endl;
}

So you can read it directly , That is, when our configuration file does not exist , Use the original code to get , When the configuration file exists , Use the... Of the configuration file IP Address . Thus, the problems of firewall and virtual machine are solved .

原网站

版权声明
本文为[qianbo_ insist]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206230438135754.html