Igmpproxy source code learning-load loadConfig and loadconfig for configuration information
Before the igmpproxy main program runs, you need to read the configuration file. The configuration file of igmpproxy is usually/etc/igmpproxy. conf or/var/igmpproxy. conf. Its content is as follows:
quickleave
mode 3
phyint ppp0 upstream ratelimit 0 threshold 1
phyint br0 downstream ratelimit 0 threshold 1
The main function calls loadConfig () to load the configuration file information. The code for loading the configuration file is mainly in config. c. Before analyzing the specific implementation of loadConfig, we should first understand the struct vifconfig in config. c. This struct records configurations such as the igmpproxy port.
struct vifconfig {
Char * name; // port name, such as eth0
Invalid state; // port status 0-Invalid Port 1
Intratelimit; // The access rate limit.
Intthreshold; // TTl threshold
// Keep allowed nets for VIF.
Struct SubnetList * allowednets; // structure of the subnet IP address and subnet mask
// Next config in list...
Struct vifconfig * next; // next node
};
In config. c, the global variable vifconf of struct vifconfig is defined.
This global variable saves the configuration information we read from the configuration file.The main function of laodConfig () is to record the information in the configuration file in a linked list that can be accessed through vifconf. Then the main function calls igmpProxyInit (). This function accesses vifconf for related configuration. Of course, igmpProxyInit () has other functions.
LoadConfig
LoadConfigUnderstand the main process of loading configuration information.
Void initCommonConfig ()
LoadConfig first calls the initCommonConfig () function to initialize some public constants.
OpenConfigFile (configFile)
Opening the configuration file is easy to understand. In addition to opening the configuration file, this function also allocates memory space for the global pointer variable iBuffer. IBuffer is used to save the 512 bytes read from the configuration file each time. The implementation of igmpproxy's loading configuration information is: each time the data read from the configuration file up to 512 bytes (in fact one row may be read) is put in IBuffer, then parse Every token from iBuffer (for more details about iBuffer in nextConfigToken ).
NextConfigToken ()
As the name suggests, nextConfigToken () is used to parse a token from igmpproxy. conf. However, not every token accesses igmpproxy once. in conf, The READ_BUFFER_SIZE data is retrieved at a time in the buffer zone iBuffer, and then parsed from a word in iBuffer. When the 512 bytes are parsed, (bufPtr = readSize) is true, and fread generates 512 bytes of data.
If igmpproxy. conf is read and all the read data is parsed in nextConfigToken, (readSize <READ_BUFFER_SIZE & bufPtr = readSize) is true, then NULL is returned. Because nextConfigToken () uses the buffer iBuffer, it does not access igmpproxy. conf every time it runs. When running nextConfigToken for the first time, we must execute fread from the next igmpproxy. conf reads 512 bytes of data. When we execute nextConfigToken for the second time, because the data we read for the first time in iBuffer has not been used up, we do not need to use fread once.
Core loadConfig Process
In the loadConfig () function, after the first execution of nextConfigToken to obtain a token, we enter the core process of loadConfig, that is, the configuration information parsing and the member variables that parse the configuration information into the struct vifconfig are stored in the global variable vifconf (such as port information, IP address, and so on ). The correct configuration file may contain three types of information, namely phyint, quickleave, and mode. LoadConfig matches the token with the three words to determine what kind of processing is required. (The official source code I downloaded does not support mode. This can be implemented by modifying the source code. We can also configure the igmpproxy file. write Other configuration information in conf, and then add the processing method in loadConfig)
If you find that the current read information is about phyint, you can call parsePhyintToken () to parse the information according to phyint rules and save the information in the form of struct vifconfig to the pointer tmpPtr,
Then pass
CurrPtr
String to vifconf. The following sections describe parsePhyintToken. If quickleave is read, it is written to commonConfig. fastUpstreamLeave = 1 in public configuration;
ParsePhyintToken
The return value is a struct pointer of the struct vifconfig type. When you enter parsePhyintToken, the token must be the name of the network interface, for example (eth0, ppp0, br0). Therefore, the size of the first token cannot exceed sizeof (struct ifreq *) NULL) -> ifr_name ). Next, initialize the member variables of the tmpPtr struct pointer.
tmpPtr->next = NULL; // Important to avoid seg fault...
tmpPtr->ratelimit = 0;
tmpPtr->threshold = 1;
tmpPtr->state = IF_STATE_DOWNSTREAM;
tmpPtr->allowednets = NULL
After initialization, copy the token (the interface name at this time) to tmpPtr-> name
strcpy(tmpPtr->name, token);
Then, use keywords such as altnet and upstream to match the tokens one by one. To match altnet, you need to use parseSubnetAddress for further parsing:
*anetPtr = parseSubnetAddress(token);
When upstream, downstream, disabled, ratelimit, and threshold are matched, the member variables of tmpPtr are directly set. For example:
else if(strcmp("upstream", token)==0) {
// Upstream
IF_DEBUG log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
tmpPtr->state = IF_STATE_UPSTREAM;
ParseSubnetAddress
Resolve the subnet IP address in the format of a. B. c. d/n to the struct SubnetList.
struct SubnetList {
uint32 subnet_addr;
uint32 subnet_mask;
struct SubnetList* next;
}
GetCurrentConfigToken
It is easy to explain whether the token is valid.
Summary:
LoadConfig main loop.
nextConfigToken()
while(){
phyint:
parsePhyintToken()
quickleave/mode:
Directly modify public configurations
}
ParsePhyintToken stores phyint information in vifconf through a linked list.