This repository has been archived by the owner on Mar 1, 2018. It is now read-only.
forked from wlibo666/adkill
-
Notifications
You must be signed in to change notification settings - Fork 25
/
advconfparse.c
342 lines (305 loc) · 8.14 KB
/
advconfparse.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/**
@file advconfparse.c
@date 2014/07/31
@author WangChunyan
@version 1.0.0
@brief 去广告配置解析接口
@note
去广告配置应用中解析用户配置的相关接口
*/
#include <linux/mm.h>
#include "advconfparse.h"
#include "advhash.h"
extern struct mutex g_advconf_mutex;
#ifdef ADVKILL_CHECK_MEM
extern unsigned long long int g_calloc_times;
extern unsigned long long int g_calloc_size;
extern unsigned long long int g_free_times;
extern unsigned long long int g_free_size;
#endif
/**
配置行内容结构体,临时保存配置行中的每一个字段
*/
struct adv_conf_data
{
char field1; ///< 操作类型
char field2[ADV_CONF_FIELD_2_LEN]; ///< 第二个字段
char field3[ADV_CONF_FIELD_3_LEN]; ///< 第三个字段
char field4[ADV_CONF_FIELD_4_LEN]; ///< 第四个字段
char field5[ADV_CONF_FIELD_5_LEN]; ///< 第五个字段
char field6[ADV_CONF_FIELD_6_LEN]; ///< 第六个字段
};
/**
将输入配置行转换到结构体 adv_conf_data 中
@param linedata 输入配置行
@param data 配置保存在变量data里
@return 成功返回 ADV_KILL_OK,失败返回 ADV_KILL_FAIL
*/
static int get_advconf_line_data(char *linedata, struct adv_conf_data *data)
{
char *tmpdata = NULL;
int index = 0;
int sepnum = 0;
EnterFunction();
if(!linedata || !data)
return ADV_KILL_FAIL;
tmpdata = linedata;
while (*tmpdata != '\n' && *tmpdata != '\0')
{
if (( *tmpdata == ADV_CONF_DATA_SEPC_CHAR )&&( sepnum<5 ))
{
sepnum++;
index = 0;
tmpdata++;
continue;
}
switch(sepnum)
{
case 0:
data->field1 = (*tmpdata);
break;
case 1:
data->field2[index] = (*tmpdata);
break;
case 2:
data->field3[index] = (*tmpdata);
break;
case 3:
data->field4[index] = (*tmpdata);
break;
case 4:
data->field5[index] = (*tmpdata);
break;
case 5:
data->field6[index] = (*tmpdata);
break;
default:
break;
}
tmpdata++;
index++;
}
LeaveFunction();
return ADV_KILL_OK;
}
/**
解析配置操作标识
@param oper 操作字段(一个字符)
@return 返回相应的操作类型(枚举值)
*/
static int get_oper_flag(char oper)
{
switch(oper)
{
case ADV_CONF_REDIRECT_PLAYER:
return adv_redirect_player;
case ADV_CONF_DROP_REQUEST:
return adv_drop_request;
case ADV_CONF_MODIFY_URL:
return adv_modify_url;
case ADV_CONF_BAD_GW:
return adv_bad_gw;
case ADV_CONF_FAKE_PACK:
return adv_fake_pack;
default:
return adv_redirect_player;
}
}
static int parse_str2int(char *str)
{
int number = 0;
sscanf(str, "%d", &number);
return number;
}
static int get_tag_num_from_tagdata(char *tagdata, int len)
{
char *tmpdata = tagdata;
int i = 0;
int num = 0;
if(strlen(tmpdata) < 1)
return 0;
while(i<len)
{
if(*tmpdata == ADV_TAG_SEPARATIR_CHAR)
{
num++;
}
i++;
tmpdata++;
}
return (num+1);
}
/**
解析配置行中URL配置规则
@param data 要解析的配置结构体
@param node 要保存到的配置哈希节点
@return 成功返回 ADV_KILL_OK,失败返回 ADV_KILL_FAIL
*/
static int parse_advconf_url(struct adv_conf_data *data, struct advconf_hashnode *node)
{
int i = 0;
char *tmpsurlbegin = NULL;
char *tmpsurlend = NULL;
char *tmpdurlbegin = NULL;
char *tmpdurlend = NULL;
if (!data || !node)
return ADV_KILL_FAIL;
node->mapnum = get_tag_num_from_tagdata(data->field4, strlen(data->field4));
node->map = (struct advconf_hostmap *)ADVKILL_CALLOC(node->mapnum, sizeof(struct advconf_hostmap));
if (node->map == NULL)
return ADV_KILL_FAIL;
tmpsurlbegin = data->field4;
tmpdurlbegin = data->field6;
for (i=0; i<node->mapnum; i++)
{
//surl
tmpsurlend = strchr(tmpsurlbegin, ADV_TAG_SEPARATIR_CHAR);
if (tmpsurlend == NULL)
node->map[i].surllen = strlen(tmpsurlbegin);
else
node->map[i].surllen = (tmpsurlend - tmpsurlbegin);
if (node->map[i].surllen > 0)
{
node->map[i].surl = (char *)ADVKILL_CALLOC(1, node->map[i].surllen+1);
if (node->map[i].surl == NULL)
{
return ADV_KILL_FAIL;
}
memcpy(node->map[i].surl, tmpsurlbegin, node->map[i].surllen);
}
tmpsurlbegin += (node->map[i].surllen + 1);
//durl
tmpdurlend = strchr(tmpdurlbegin, ADV_TAG_SEPARATIR_CHAR);
if (tmpdurlend == NULL)
node->map[i].durllen = strlen(tmpdurlbegin);
else
node->map[i].durllen = (tmpdurlend - tmpdurlbegin);
if (node->map[i].durllen > 0)
{
node->map[i].durl = (char *)ADVKILL_CALLOC(1, node->map[i].durllen+1);
if (node->map[i].durl == NULL)
{
return ADV_KILL_FAIL;
}
memcpy(node->map[i].durl, tmpdurlbegin, node->map[i].durllen);
}
tmpdurlbegin += (node->map[i].durllen + 1);
}
return ADV_KILL_OK;
}
/**
解析单条配置,并保存到哈希节点内
@param data 配置临时结构体
@param node 解析后保存的结构体地址
@return 成功返回 ADV_KILL_OK,失败返回 ADV_KILL_FAIL。
*/
static int parse_advconf_node_from_adv_conf_data(struct adv_conf_data *data, struct advconf_hashnode **node)
{
struct advconf_hashnode *tmpnode = NULL;
EnterFunction();
if(!data)
return ADV_KILL_FAIL;
tmpnode = (struct advconf_hashnode *)ADVKILL_CALLOC(1, sizeof(struct advconf_hashnode));
if(!tmpnode)
return ADV_KILL_FAIL;
//oper flag
tmpnode->type = get_oper_flag(data->field1);
//index
tmpnode->index = parse_str2int(data->field2);
//shost
tmpnode->s_host_len = strlen(data->field3);
tmpnode->s_host = (char *)ADVKILL_CALLOC(1, tmpnode->s_host_len+1);
if (tmpnode->s_host == NULL)
{
goto exit_fail;
}
strcpy(tmpnode->s_host, data->field3);
//dhost
tmpnode->d_host_len = strlen(data->field5);
tmpnode->d_host = (char *)ADVKILL_CALLOC(1, tmpnode->d_host_len+1);
if (tmpnode->d_host == NULL)
{
goto exit_fail;
}
strcpy(tmpnode->d_host, data->field5);
//surl durl
if(tmpnode->type != adv_fake_pack)
{
if (parse_advconf_url(data, tmpnode) != ADV_KILL_OK)
{
goto exit_fail;
}
} else {
tmpnode->mapnum = 1;
tmpnode->map = (struct advconf_hostmap *)ADVKILL_CALLOC(1, sizeof(struct advconf_hostmap));
tmpnode->map[0].surllen = strlen(data->field4);
tmpnode->map[0].surl = (char *)ADVKILL_CALLOC(1, tmpnode->map[0].surllen+1);
if (tmpnode->map[0].surl == NULL)
{
ADVKILL_FREE(tmpnode->map, sizeof(struct advconf_hostmap));
return ADV_KILL_FAIL;
}
memcpy(tmpnode->map[0].surl, data->field4, tmpnode->map[0].surllen);
tmpnode->map[0].durllen = strlen(data->field6);
tmpnode->map[0].durl = (char *)ADVKILL_CALLOC(1, tmpnode->map[0].durllen+1);
if (tmpnode->map[0].durl == NULL)
{
ADVKILL_FREE(tmpnode->map[0].surl, tmpnode->map[0].surllen+1);
ADVKILL_FREE(tmpnode->map, sizeof(struct advconf_hostmap));
return ADV_KILL_FAIL;
}
memcpy(tmpnode->map[0].durl, data->field6, tmpnode->map[0].durllen);
}
*node = tmpnode;
return ADV_KILL_OK;
exit_fail:
return ADV_KILL_FAIL;
}
#ifdef ADVKILL_PRINT_DEBUG_INFO
static void print_adv_conf_data(struct adv_conf_data *data)
{
if(!data)
return;
printk(KERN_ALERT "field1[%c],field2[%s],field3[%s],field4[%s],field5[%s],field6[%s]\n\n",
data->field1, data->field2, data->field3, data->field4, data->field5, data->field6);
}
#endif
/**
解析一行配置,解析完成后配置存放在结构体 advconf_hashtable 里
@param linedata 输入配置行
@param table 配置哈希表首地址
@param tablenum 配置哈希表大小
@return 成功返回ADV_KILL_OK,失败返回ADV_KILL_FAIL
*/
int parse_advconf_line_data(char *linedata, struct advconf_hashtable *table, int tablenum)
{
struct advconf_hashnode *advconfnode = NULL;
struct adv_conf_data *data = NULL;
if(!linedata || !table)
return ADV_KILL_FAIL;
data = (struct adv_conf_data *)ADVKILL_CALLOC(1, sizeof(struct adv_conf_data));
if (data == NULL)
{
return ADV_KILL_FAIL;
}
get_advconf_line_data(linedata, data);
#ifdef ADVKILL_PRINT_DEBUG_INFO
print_adv_conf_data(data);
#endif
if (parse_advconf_node_from_adv_conf_data(data, &advconfnode) != ADV_KILL_OK)
{
ADVKILL_FREE(data, sizeof(struct adv_conf_data));
data = NULL;
advconf_hashnode_free(advconfnode);
return ADV_KILL_FAIL;
}
#ifdef ADVKILL_PRINT_DEBUG_INFO
advconf_hashnode_print(advconfnode);
#endif
ADVKILL_MUTEX_LOCK(&g_advconf_mutex);
advconf_hashnode_add(table, tablenum, advconfnode);
ADVKILL_MUTEX_UNLOCK(&g_advconf_mutex);
ADVKILL_FREE(data, sizeof(struct adv_conf_data));
data = NULL;
return ADV_KILL_OK;
}