1 /**
2 * Copyright (C) 2008 Happy Fish / YuQing
3 *
4 * FastDFS may be copied only under the terms of the GNU General
5 * Public License V3, which may be found in the FastDFS source kit.
6 * Please visit the FastDFS Home Page http://www.fastken.com/ for more detail.
7 **/
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <limits.h>
12 #include <netdb.h>
13 #include "fastcommon/logger.h"
14 #include "fastcommon/sockopt.h"
15 #include "fastcommon/shared_func.h"
16 #include "fastcommon/local_ip_func.h"
17 #include "tracker_proto.h"
18 #include "fdfs_global.h"
19 #include "fdfs_shared_func.h"
20
21
fdfs_server_contain(TrackerServerInfo * pServerInfo,const char * target_ip,const int target_port)22 bool fdfs_server_contain(TrackerServerInfo *pServerInfo,
23 const char *target_ip, const int target_port)
24 {
25 ConnectionInfo *conn;
26 ConnectionInfo *end;
27
28 if (pServerInfo->count == 1)
29 {
30 return FC_CONNECTION_SERVER_EQUAL(pServerInfo->connections[0],
31 target_ip, target_port);
32 }
33 else if (pServerInfo->count == 2)
34 {
35 return FC_CONNECTION_SERVER_EQUAL(pServerInfo->connections[0],
36 target_ip, target_port) ||
37 FC_CONNECTION_SERVER_EQUAL(pServerInfo->connections[1],
38 target_ip, target_port);
39 }
40
41 end = pServerInfo->connections + pServerInfo->count;
42 for (conn=pServerInfo->connections; conn<end; conn++)
43 {
44 if (FC_CONNECTION_SERVER_EQUAL(*conn, target_ip, target_port))
45 {
46 return true;
47 }
48 }
49
50 return false;
51 }
52
fdfs_server_contain_ex(TrackerServerInfo * pServer1,TrackerServerInfo * pServer2)53 bool fdfs_server_contain_ex(TrackerServerInfo *pServer1,
54 TrackerServerInfo *pServer2)
55 {
56 ConnectionInfo *conn;
57 ConnectionInfo *end;
58
59 if (pServer1->count == 1)
60 {
61 return fdfs_server_contain1(pServer2, pServer1->connections + 0);
62 }
63 else if (pServer1->count == 2)
64 {
65 if (fdfs_server_contain1(pServer2, pServer1->connections + 0))
66 {
67 return true;
68 }
69 return fdfs_server_contain1(pServer2, pServer1->connections + 1);
70 }
71
72 end = pServer1->connections + pServer1->count;
73 for (conn=pServer1->connections; conn<end; conn++)
74 {
75 if (fdfs_server_contain1(pServer2, conn))
76 {
77 return true;
78 }
79 }
80
81 return false;
82 }
83
fdfs_server_equal(TrackerServerInfo * pServer1,TrackerServerInfo * pServer2)84 bool fdfs_server_equal(TrackerServerInfo *pServer1,
85 TrackerServerInfo *pServer2)
86 {
87 ConnectionInfo *conn;
88 ConnectionInfo *end;
89
90 if (pServer1->count != pServer2->count)
91 {
92 return false;
93 }
94
95 if (pServer1->count == 1)
96 {
97 return (pServer1->connections->port == pServer2->connections->port &&
98 strcmp(pServer1->connections->ip_addr, pServer2->connections->ip_addr) == 0);
99 }
100
101 end = pServer1->connections + pServer1->count;
102 for (conn=pServer1->connections; conn<end; conn++)
103 {
104 if (!fdfs_server_contain1(pServer2, conn))
105 {
106 return false;
107 }
108 }
109
110 return true;
111 }
112
fdfs_server_contain_local_service(TrackerServerInfo * pServerInfo,const int target_port)113 bool fdfs_server_contain_local_service(TrackerServerInfo *pServerInfo,
114 const int target_port)
115 {
116 const char *current_ip;
117
118 current_ip = get_first_local_ip();
119 while (current_ip != NULL)
120 {
121 if (fdfs_server_contain(pServerInfo, current_ip, target_port))
122 {
123 return true;
124 }
125 current_ip = get_next_local_ip(current_ip);
126 }
127
128 return false;
129 }
130
fdfs_tracker_group_get_server(TrackerServerGroup * pGroup,const char * target_ip,const int target_port)131 TrackerServerInfo *fdfs_tracker_group_get_server(TrackerServerGroup *pGroup,
132 const char *target_ip, const int target_port)
133 {
134 TrackerServerInfo *pServer;
135 TrackerServerInfo *pEnd;
136
137 pEnd = pGroup->servers + pGroup->server_count;
138 for (pServer=pGroup->servers; pServer<pEnd; pServer++)
139 {
140 if (fdfs_server_contain(pServer, target_ip, target_port))
141 {
142 return pServer;
143 }
144 }
145
146 return NULL;
147 }
148
fdfs_server_sock_reset(TrackerServerInfo * pServerInfo)149 void fdfs_server_sock_reset(TrackerServerInfo *pServerInfo)
150 {
151 ConnectionInfo *conn;
152 ConnectionInfo *end;
153
154 if (pServerInfo->count == 1)
155 {
156 pServerInfo->connections[0].sock = -1;
157 }
158 else if (pServerInfo->count == 2)
159 {
160 pServerInfo->connections[0].sock = -1;
161 pServerInfo->connections[1].sock = -1;
162 }
163 else
164 {
165 end = pServerInfo->connections + pServerInfo->count;
166 for (conn=pServerInfo->connections; conn<end; conn++)
167 {
168 conn->sock = -1;
169 }
170 }
171 }
172
fdfs_get_tracker_leader_index_ex(TrackerServerGroup * pServerGroup,const char * leaderIp,const int leaderPort)173 int fdfs_get_tracker_leader_index_ex(TrackerServerGroup *pServerGroup,
174 const char *leaderIp, const int leaderPort)
175 {
176 TrackerServerInfo *pServer;
177 TrackerServerInfo *pEnd;
178
179 if (pServerGroup->server_count == 0)
180 {
181 return -1;
182 }
183
184 pEnd = pServerGroup->servers + pServerGroup->server_count;
185 for (pServer=pServerGroup->servers; pServer<pEnd; pServer++)
186 {
187 if (fdfs_server_contain(pServer, leaderIp, leaderPort))
188 {
189 return pServer - pServerGroup->servers;
190 }
191 }
192
193 return -1;
194 }
195
fdfs_parse_storage_reserved_space(IniContext * pIniContext,FDFSStorageReservedSpace * pStorageReservedSpace)196 int fdfs_parse_storage_reserved_space(IniContext *pIniContext,
197 FDFSStorageReservedSpace *pStorageReservedSpace)
198 {
199 int result;
200 int len;
201 char *pReservedSpaceStr;
202 int64_t storage_reserved;
203
204 pReservedSpaceStr = iniGetStrValue(NULL, \
205 "reserved_storage_space", pIniContext);
206 if (pReservedSpaceStr == NULL)
207 {
208 pStorageReservedSpace->flag = \
209 TRACKER_STORAGE_RESERVED_SPACE_FLAG_MB;
210 pStorageReservedSpace->rs.mb = FDFS_DEF_STORAGE_RESERVED_MB;
211 return 0;
212 }
213 if (*pReservedSpaceStr == '\0')
214 {
215 logError("file: "__FILE__", line: %d, " \
216 "item \"reserved_storage_space\" is empty!", \
217 __LINE__);
218 return EINVAL;
219 }
220
221 len = strlen(pReservedSpaceStr);
222 if (*(pReservedSpaceStr + len - 1) == '%')
223 {
224 char *endptr;
225 pStorageReservedSpace->flag = \
226 TRACKER_STORAGE_RESERVED_SPACE_FLAG_RATIO;
227 endptr = NULL;
228 *(pReservedSpaceStr + len - 1) = '\0';
229 pStorageReservedSpace->rs.ratio = \
230 strtod(pReservedSpaceStr, &endptr);
231 if (endptr != NULL && *endptr != '\0')
232 {
233 logError("file: "__FILE__", line: %d, " \
234 "item \"reserved_storage_space\": %s%%"\
235 " is invalid!", __LINE__, \
236 pReservedSpaceStr);
237 return EINVAL;
238 }
239
240 if (pStorageReservedSpace->rs.ratio <= 0.00 || \
241 pStorageReservedSpace->rs.ratio >= 100.00)
242 {
243 logError("file: "__FILE__", line: %d, " \
244 "item \"reserved_storage_space\": %s%%"\
245 " is invalid!", __LINE__, \
246 pReservedSpaceStr);
247 return EINVAL;
248 }
249
250 pStorageReservedSpace->rs.ratio /= 100.00;
251 return 0;
252 }
253
254 if ((result=parse_bytes(pReservedSpaceStr, 1, &storage_reserved)) != 0)
255 {
256 return result;
257 }
258
259 pStorageReservedSpace->flag = TRACKER_STORAGE_RESERVED_SPACE_FLAG_MB;
260 pStorageReservedSpace->rs.mb = storage_reserved / FDFS_ONE_MB;
261 return 0;
262 }
263
fdfs_storage_reserved_space_to_string(FDFSStorageReservedSpace * pStorageReservedSpace,char * buff)264 const char *fdfs_storage_reserved_space_to_string(FDFSStorageReservedSpace \
265 *pStorageReservedSpace, char *buff)
266 {
267 if (pStorageReservedSpace->flag == \
268 TRACKER_STORAGE_RESERVED_SPACE_FLAG_MB)
269 {
270 sprintf(buff, "%d MB", pStorageReservedSpace->rs.mb);
271 }
272 else
273 {
274 sprintf(buff, "%.2f%%", 100.00 * \
275 pStorageReservedSpace->rs.ratio);
276 }
277
278 return buff;
279 }
280
fdfs_storage_reserved_space_to_string_ex(const bool flag,const int space_mb,const int total_mb,const double space_ratio,char * buff)281 const char *fdfs_storage_reserved_space_to_string_ex(const bool flag, \
282 const int space_mb, const int total_mb, const double space_ratio, \
283 char *buff)
284 {
285 if (flag == TRACKER_STORAGE_RESERVED_SPACE_FLAG_MB)
286 {
287 sprintf(buff, "%d MB", space_mb);
288 }
289 else
290 {
291 sprintf(buff, "%d MB(%.2f%%)", (int)(total_mb * space_ratio), \
292 100.00 * space_ratio);
293 }
294
295 return buff;
296 }
297
fdfs_get_storage_reserved_space_mb(const int total_mb,FDFSStorageReservedSpace * pStorageReservedSpace)298 int fdfs_get_storage_reserved_space_mb(const int total_mb, \
299 FDFSStorageReservedSpace *pStorageReservedSpace)
300 {
301 if (pStorageReservedSpace->flag == \
302 TRACKER_STORAGE_RESERVED_SPACE_FLAG_MB)
303 {
304 return pStorageReservedSpace->rs.mb;
305 }
306 else
307 {
308 return (int)(total_mb * pStorageReservedSpace->rs.ratio);
309 }
310 }
311
fdfs_check_reserved_space(FDFSGroupInfo * pGroup,FDFSStorageReservedSpace * pStorageReservedSpace)312 bool fdfs_check_reserved_space(FDFSGroupInfo *pGroup, \
313 FDFSStorageReservedSpace *pStorageReservedSpace)
314 {
315 if (pStorageReservedSpace->flag == \
316 TRACKER_STORAGE_RESERVED_SPACE_FLAG_MB)
317 {
318 return pGroup->free_mb > pStorageReservedSpace->rs.mb;
319 }
320 else
321 {
322 if (pGroup->total_mb == 0)
323 {
324 return false;
325 }
326
327 /*
328 logInfo("storage=%.4f, rs.ratio=%.4f",
329 ((double)pGroup->free_mb / (double)pGroup->total_mb),
330 pStorageReservedSpace->rs.ratio);
331 */
332
333 return ((double)pGroup->free_mb / (double)pGroup->total_mb) > \
334 pStorageReservedSpace->rs.ratio;
335 }
336 }
337
fdfs_check_reserved_space_trunk(FDFSGroupInfo * pGroup,FDFSStorageReservedSpace * pStorageReservedSpace)338 bool fdfs_check_reserved_space_trunk(FDFSGroupInfo *pGroup, \
339 FDFSStorageReservedSpace *pStorageReservedSpace)
340 {
341 if (pStorageReservedSpace->flag == \
342 TRACKER_STORAGE_RESERVED_SPACE_FLAG_MB)
343 {
344 return (pGroup->free_mb + pGroup->trunk_free_mb >
345 pStorageReservedSpace->rs.mb);
346 }
347 else
348 {
349 if (pGroup->total_mb == 0)
350 {
351 return false;
352 }
353
354 /*
355 logInfo("storage trunk=%.4f, rs.ratio=%.4f",
356 ((double)(pGroup->free_mb + pGroup->trunk_free_mb) / \
357 (double)pGroup->total_mb), pStorageReservedSpace->rs.ratio);
358 */
359
360 return ((double)(pGroup->free_mb + pGroup->trunk_free_mb) / \
361 (double)pGroup->total_mb) > pStorageReservedSpace->rs.ratio;
362 }
363 }
364
fdfs_check_reserved_space_path(const int64_t total_mb,const int64_t free_mb,const int avg_mb,FDFSStorageReservedSpace * pStorageReservedSpace)365 bool fdfs_check_reserved_space_path(const int64_t total_mb, \
366 const int64_t free_mb, const int avg_mb, \
367 FDFSStorageReservedSpace *pStorageReservedSpace)
368 {
369 if (pStorageReservedSpace->flag == \
370 TRACKER_STORAGE_RESERVED_SPACE_FLAG_MB)
371 {
372 return free_mb > avg_mb;
373 }
374 else
375 {
376 if (total_mb == 0)
377 {
378 return false;
379 }
380
381 /*
382 logInfo("storage path, free_mb=%"PRId64 \
383 ", total_mb=%"PRId64", " \
384 "real ratio=%.4f, rs.ratio=%.4f", \
385 free_mb, total_mb, ((double)free_mb / total_mb), \
386 pStorageReservedSpace->rs.ratio);
387 */
388
389 return ((double)free_mb / (double)total_mb) > \
390 pStorageReservedSpace->rs.ratio;
391 }
392 }
393
fdfs_connection_pool_init(const char * config_filename,IniContext * pItemContext)394 int fdfs_connection_pool_init(const char *config_filename, \
395 IniContext *pItemContext)
396 {
397 g_use_connection_pool = iniGetBoolValue(NULL, "use_connection_pool", \
398 pItemContext, false);
399 if (!g_use_connection_pool)
400 {
401 return 0;
402 }
403
404 g_connection_pool_max_idle_time = iniGetIntValue(NULL, \
405 "connection_pool_max_idle_time", \
406 pItemContext, 3600);
407 if (g_connection_pool_max_idle_time <= 0)
408 {
409 logError("file: "__FILE__", line: %d, " \
410 "connection_pool_max_idle_time: %d of conf " \
411 "filename: \"%s\" is invalid!", __LINE__, \
412 g_connection_pool_max_idle_time, config_filename);
413 return EINVAL;
414 }
415
416 return conn_pool_init(&g_connection_pool, g_fdfs_connect_timeout, \
417 0, g_connection_pool_max_idle_time);
418 }
419
fdfs_connection_pool_destroy()420 void fdfs_connection_pool_destroy()
421 {
422 conn_pool_destroy(&g_connection_pool);
423 }
424
fdfs_set_log_rotate_size(LogContext * pContext,const int64_t log_rotate_size)425 void fdfs_set_log_rotate_size(LogContext *pContext, const int64_t log_rotate_size)
426 {
427 if (log_rotate_size > 0)
428 {
429 pContext->rotate_size = log_rotate_size;
430 log_set_rotate_time_format(pContext, "%Y%m%d_%H%M%S");
431 }
432 else
433 {
434 pContext->rotate_size = 0;
435 log_set_rotate_time_format(pContext, "%Y%m%d");
436 }
437 }
438
fdfs_parse_server_info_ex(char * server_str,const int default_port,TrackerServerInfo * pServer,const bool resolve)439 int fdfs_parse_server_info_ex(char *server_str, const int default_port,
440 TrackerServerInfo *pServer, const bool resolve)
441 {
442 char *pColon;
443 char *hosts[FDFS_MULTI_IP_MAX_COUNT];
444 ConnectionInfo *conn;
445 int port;
446 int i;
447
448 memset(pServer, 0, sizeof(TrackerServerInfo));
449 if ((pColon=strrchr(server_str, ':')) == NULL)
450 {
451 logInfo("file: "__FILE__", line: %d, "
452 "no port part in %s, set port to %d",
453 __LINE__, server_str, default_port);
454 port = default_port;
455 }
456 else
457 {
458 *pColon = '\0';
459 port = atoi(pColon + 1);
460 }
461
462 conn = pServer->connections;
463 pServer->count = splitEx(server_str, ',',
464 hosts, FDFS_MULTI_IP_MAX_COUNT);
465 for (i=0; i<pServer->count; i++)
466 {
467 if (resolve)
468 {
469 if (getIpaddrByName(hosts[i], conn->ip_addr,
470 sizeof(conn->ip_addr)) == INADDR_NONE)
471 {
472 logError("file: "__FILE__", line: %d, "
473 "host \"%s\" is invalid, error info: %s",
474 __LINE__, hosts[i], hstrerror(h_errno));
475 return EINVAL;
476 }
477 }
478 else
479 {
480 snprintf(conn->ip_addr, sizeof(conn->ip_addr), "%s", hosts[i]);
481 }
482 conn->port = port;
483 conn->sock = -1;
484 conn++;
485 }
486
487 return 0;
488 }
489
fdfs_server_info_to_string_ex(const TrackerServerInfo * pServer,const int port,char * buff,const int buffSize)490 int fdfs_server_info_to_string_ex(const TrackerServerInfo *pServer,
491 const int port, char *buff, const int buffSize)
492 {
493 const ConnectionInfo *conn;
494 const ConnectionInfo *end;
495 int len;
496
497 if (pServer->count <= 0)
498 {
499 *buff = '\0';
500 return 0;
501 }
502 if (pServer->count == 1)
503 {
504 return snprintf(buff, buffSize, "%s:%d",
505 pServer->connections[0].ip_addr, port);
506 }
507
508 len = snprintf(buff, buffSize, "%s", pServer->connections[0].ip_addr);
509 end = pServer->connections + pServer->count;
510 for (conn=pServer->connections + 1; conn<end; conn++)
511 {
512 len += snprintf(buff + len, buffSize - len, ",%s", conn->ip_addr);
513 }
514 len += snprintf(buff + len, buffSize - len, ":%d", port);
515 return len;
516 }
517
fdfs_get_ip_type(const char * ip)518 int fdfs_get_ip_type(const char* ip)
519 {
520 if (ip == NULL || (int)strlen(ip) < 8)
521 {
522 return FDFS_IP_TYPE_UNKNOWN;
523 }
524
525 if (memcmp(ip, "10.", 3) == 0)
526 {
527 return FDFS_IP_TYPE_PRIVATE_10;
528 }
529 if (memcmp(ip, "192.168.", 8) == 0)
530 {
531 return FDFS_IP_TYPE_PRIVATE_192;
532 }
533
534 if (memcmp(ip, "172.", 4) == 0)
535 {
536 int b;
537 b = atoi(ip + 4);
538 if (b >= 16 && b < 32)
539 {
540 return FDFS_IP_TYPE_PRIVATE_172;
541 }
542 }
543
544 return FDFS_IP_TYPE_OUTER;
545 }
546
fdfs_check_server_ips(const TrackerServerInfo * pServer,char * error_info,const int error_size)547 int fdfs_check_server_ips(const TrackerServerInfo *pServer,
548 char *error_info, const int error_size)
549 {
550 int type0;
551 int type1;
552 if (pServer->count == 1)
553 {
554 *error_info = '\0';
555 return 0;
556 }
557
558 if (pServer->count <= 0)
559 {
560 logError("file: "__FILE__", line: %d, "
561 "empty server", __LINE__);
562 return EINVAL;
563 }
564
565 if (pServer->count > FDFS_MULTI_IP_MAX_COUNT)
566 {
567 snprintf(error_info, error_size,
568 "too many server ip addresses: %d, exceeds %d",
569 pServer->count, FDFS_MULTI_IP_MAX_COUNT);
570 return EINVAL;
571 }
572
573 type0 = fdfs_get_ip_type(pServer->connections[0].ip_addr);
574 type1 = fdfs_get_ip_type(pServer->connections[1].ip_addr);
575 if (type0 == type1)
576 {
577 snprintf(error_info, error_size,
578 "invalid ip addresses %s and %s, "
579 "one MUST be an inner IP and another is a outer IP, "
580 "or two different types of inner IP addresses",
581 pServer->connections[0].ip_addr,
582 pServer->connections[1].ip_addr);
583 return EINVAL;
584 }
585
586 *error_info = '\0';
587 return 0;
588 }
589
fdfs_parse_multi_ips_ex(char * ip_str,FDFSMultiIP * ip_addrs,char * error_info,const int error_size,const bool resolve)590 int fdfs_parse_multi_ips_ex(char *ip_str, FDFSMultiIP *ip_addrs,
591 char *error_info, const int error_size, const bool resolve)
592 {
593 char *hosts[FDFS_MULTI_IP_MAX_COUNT];
594 int i;
595
596 ip_addrs->index = 0;
597 ip_addrs->count = splitEx(ip_str, ',', hosts, FDFS_MULTI_IP_MAX_COUNT);
598 for (i=0; i<ip_addrs->count; i++)
599 {
600 if (resolve)
601 {
602 if (getIpaddrByName(hosts[i], ip_addrs->ips[i].address,
603 sizeof(ip_addrs->ips[i].address)) == INADDR_NONE)
604 {
605 snprintf(error_info, error_size,
606 "host \"%s\" is invalid, error info: %s",
607 hosts[i], hstrerror(h_errno));
608 return EINVAL;
609 }
610 }
611 else
612 {
613 snprintf(ip_addrs->ips[i].address,
614 sizeof(ip_addrs->ips[i].address), "%s", hosts[i]);
615 }
616
617 ip_addrs->ips[i].type = fdfs_get_ip_type(ip_addrs->ips[i].address);
618 if (ip_addrs->ips[i].type == FDFS_IP_TYPE_UNKNOWN)
619 {
620 snprintf(error_info, error_size,
621 "ip address \"%s\" is invalid",
622 ip_addrs->ips[i].address);
623 return EINVAL;
624 }
625 }
626
627 *error_info = '\0';
628 return 0;
629 }
630
fdfs_multi_ips_to_string_ex(const FDFSMultiIP * ip_addrs,const char seperator,char * buff,const int buffSize)631 int fdfs_multi_ips_to_string_ex(const FDFSMultiIP *ip_addrs,
632 const char seperator, char *buff, const int buffSize)
633 {
634 int i;
635 int len;
636
637 if (ip_addrs->count <= 0)
638 {
639 *buff = '\0';
640 return 0;
641 }
642 if (ip_addrs->count == 1)
643 {
644 return snprintf(buff, buffSize, "%s",
645 ip_addrs->ips[0].address);
646 }
647
648 len = snprintf(buff, buffSize, "%s", ip_addrs->ips[0].address);
649 for (i=1; i<ip_addrs->count; i++)
650 {
651 len += snprintf(buff + len, buffSize - len, "%c%s",
652 seperator, ip_addrs->ips[i].address);
653 }
654 return len;
655 }
656
fdfs_get_ipaddr_by_peer_ip(const FDFSMultiIP * ip_addrs,const char * client_ip)657 const char *fdfs_get_ipaddr_by_peer_ip(const FDFSMultiIP *ip_addrs,
658 const char *client_ip)
659 {
660 int ip_type;
661 int index;
662 if (ip_addrs->count == 1)
663 {
664 return ip_addrs->ips[0].address;
665 }
666
667 if (ip_addrs->count <= 0)
668 {
669 return "";
670 }
671
672 ip_type = fdfs_get_ip_type(client_ip);
673 index = ip_addrs->ips[FDFS_MULTI_IP_INDEX_OUTER].type == ip_type ?
674 FDFS_MULTI_IP_INDEX_OUTER : FDFS_MULTI_IP_INDEX_INNER;
675 return ip_addrs->ips[index].address;
676 }
677
fdfs_check_and_format_ips(FDFSMultiIP * ip_addrs,char * error_info,const int error_size)678 int fdfs_check_and_format_ips(FDFSMultiIP *ip_addrs,
679 char *error_info, const int error_size)
680 {
681 FDFSIPInfo swap_ip;
682 if (ip_addrs->count == 1)
683 {
684 *error_info = '\0';
685 return 0;
686 }
687
688 if (ip_addrs->count <= 0)
689 {
690 logError("file: "__FILE__", line: %d, "
691 "empty server", __LINE__);
692 return EINVAL;
693 }
694
695 if (ip_addrs->count > FDFS_MULTI_IP_MAX_COUNT)
696 {
697 snprintf(error_info, error_size,
698 "too many server ip addresses: %d, exceeds %d",
699 ip_addrs->count, FDFS_MULTI_IP_MAX_COUNT);
700 return EINVAL;
701 }
702
703 if (ip_addrs->ips[FDFS_MULTI_IP_INDEX_INNER].type ==
704 ip_addrs->ips[FDFS_MULTI_IP_INDEX_OUTER].type)
705 {
706 snprintf(error_info, error_size,
707 "invalid ip addresses %s and %s, "
708 "one MUST be an inner IP and another is a outer IP, "
709 "or two different types of inner IP addresses",
710 ip_addrs->ips[0].address, ip_addrs->ips[1].address);
711 return EINVAL;
712 }
713
714 if (ip_addrs->ips[FDFS_MULTI_IP_INDEX_INNER].type == FDFS_IP_TYPE_OUTER)
715 {
716 swap_ip = ip_addrs->ips[FDFS_MULTI_IP_INDEX_INNER];
717 ip_addrs->ips[FDFS_MULTI_IP_INDEX_INNER] =
718 ip_addrs->ips[FDFS_MULTI_IP_INDEX_OUTER];
719 ip_addrs->ips[FDFS_MULTI_IP_INDEX_OUTER] = swap_ip;
720 }
721
722 *error_info = '\0';
723 return 0;
724 }
725
fdfs_set_multi_ip_index(FDFSMultiIP * multi_ip,const char * target_ip)726 void fdfs_set_multi_ip_index(FDFSMultiIP *multi_ip, const char *target_ip)
727 {
728 int i;
729 if (multi_ip->count <= 1)
730 {
731 return;
732 }
733
734 for (i=0; i<multi_ip->count; i++)
735 {
736 if (strcmp(multi_ip->ips[i].address, target_ip) == 0)
737 {
738 multi_ip->index = i;
739 break;
740 }
741 }
742 }
743
fdfs_set_server_info_index(TrackerServerInfo * pServer,const char * target_ip,const int target_port)744 void fdfs_set_server_info_index(TrackerServerInfo *pServer,
745 const char *target_ip, const int target_port)
746 {
747 int i;
748 if (pServer->count <= 1)
749 {
750 return;
751 }
752
753 for (i=0; i<pServer->count; i++)
754 {
755 if (FC_CONNECTION_SERVER_EQUAL(pServer->connections[i],
756 target_ip, target_port))
757 {
758 pServer->index = i;
759 break;
760 }
761 }
762 }
763
fdfs_set_server_info(TrackerServerInfo * pServer,const char * ip_addr,const int port)764 void fdfs_set_server_info(TrackerServerInfo *pServer,
765 const char *ip_addr, const int port)
766 {
767 pServer->count = 1;
768 pServer->index = 0;
769 conn_pool_set_server_info(pServer->connections + 0, ip_addr, port);
770 }
771
fdfs_set_server_info_ex(TrackerServerInfo * pServer,const FDFSMultiIP * ip_addrs,const int port)772 void fdfs_set_server_info_ex(TrackerServerInfo *pServer,
773 const FDFSMultiIP *ip_addrs, const int port)
774 {
775 int i;
776
777 pServer->count = ip_addrs->count;
778 pServer->index = 0;
779 for (i=0; i<ip_addrs->count; i++)
780 {
781 conn_pool_set_server_info(pServer->connections + i,
782 ip_addrs->ips[i].address, port);
783 }
784 }
785
786