You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

igs.c 37KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * --
  19. * igs.c:
  20. * Internet Gateway Search
  21. */
  22. #include "includes.h"
  23. #include "common.h"
  24. #include "libnetlink.h"
  25. #include "inet.h"
  26. #include "krnl_route.h"
  27. #include "request.h"
  28. #include "endianness.h"
  29. #include "pkts.h"
  30. #include "bmap.h"
  31. #include "qspn.h"
  32. #include "radar.h"
  33. #include "andns.h"
  34. #include "andna_cache.h"
  35. #include "netsukuku.h"
  36. #include "route.h"
  37. #include "krnl_rule.h"
  38. #include "iptunnel.h"
  39. #include "libping.h"
  40. #include "libiptc/libiptc.h"
  41. #include "mark.h"
  42. #include "igs.h"
  43. #include "err_errno.h"
  44. int igw_multi_gw_disabled;
  45. /*
  46. * bandwidth_in_8bit:
  47. * `x' is the bandwidth value expressed in Kb/s.
  48. *
  49. * Since we consider `x' expressed in this form:
  50. * x = y * 2^y;
  51. * we can store just `y' in a u_char (8bit) variable.
  52. *
  53. * `bandwidth_in_8bit' returns `y' from `x'.
  54. *
  55. * `x' cannot be greater than 3623878656 (27*2^27), so if `x' is in Kb/s the
  56. * maximum bandwidth we can store in a byte is 3.6Tb/s.
  57. */
  58. u_char
  59. bandwidth_in_8bit(u_int x)
  60. {
  61. u_int i, z, a, b;
  62. u_int diff_2;
  63. for (z = 27; z >= 0; z--) {
  64. i = z << z;
  65. if (i == x)
  66. /* x is exactly z*2^z */
  67. return (u_char) z;
  68. b = (z - 1) << (z - 1);
  69. diff_2 = (i - b) >> 1;
  70. if (x >= i - diff_2 && x <= i)
  71. /* `x' is nearer to z*2^z than (z-1)*2^(z-1) */
  72. return z;
  73. a = z == 27 ? i : (z + 1) << (z + 1);
  74. diff_2 = (a - i) >> 1;
  75. if (x <= i + diff_2 && x >= i)
  76. /* `x' is nearer to z*2^z than (z+1)*2^(z+1) */
  77. return z;
  78. }
  79. return 0;
  80. }
  81. /*
  82. * bandwidth_to_32bit: the inverse of bandwidth_in_8bit
  83. */
  84. u_int
  85. bandwidth_to_32bit(u_char x)
  86. {
  87. return (u_int) x << x;
  88. }
  89. /*
  90. * str_to_inet_gw:
  91. * The syntax of `str' is IP:devname, i.e. 192.168.1.1:eth0.
  92. * str_to_inet_gw() stores the IP in `gw'.
  93. * In `*dev' is returned the pointer to a newly allocated string containing
  94. * the device name.
  95. * On error -1 is returned.
  96. */
  97. int
  98. str_to_inet_gw(char *str, inet_prefix * gw, char **dev)
  99. {
  100. char *buf;
  101. setzero(dev, IFNAMSIZ);
  102. /* Copy :devname in `dev' */
  103. if (!(buf = rindex(str, ':')))
  104. return -1;
  105. *buf = 0;
  106. buf++;
  107. if (!*buf)
  108. /* No device was specified */
  109. return -1;
  110. if (strlen(buf) >= IFNAMSIZ)
  111. /* It is too long, truncate it */
  112. buf[IFNAMSIZ - 1] = 0;
  113. *dev = xstrndup(buf, IFNAMSIZ);
  114. /* Extract the IP from the first part of `str' */
  115. if (str_to_inet(str, gw))
  116. return -1;
  117. return 0;
  118. }
  119. /*
  120. * parse_internet_hosts
  121. *
  122. * given a string which uses the following syntax:
  123. * "hostname1:hostname2:hostname3:..."
  124. * it stores each hostname in a new mallocated array and returns it.
  125. * The number of hostnames is written in `*hosts'
  126. * On error 0 is returned.
  127. */
  128. char **
  129. parse_internet_hosts(char *str, int *hosts)
  130. {
  131. char **hnames;
  132. hnames = split_string(str, ":", hosts, MAX_INTERNET_HNAMES,
  133. MAX_INTERNET_HNAME_SZ);
  134. return hnames;
  135. }
  136. void
  137. free_internet_hosts(char **hnames, int hosts)
  138. {
  139. int i;
  140. for (i = 0; i < hosts; i++)
  141. if (hnames[i])
  142. xfree(hnames[i]);
  143. if (hnames)
  144. xfree(hnames);
  145. }
  146. /*
  147. * internet_hosts_to_ip: replace the hostnames present in
  148. * `server_opt.inet_hosts' with IP strings. The IPs are obtained
  149. * with a normal DNS resolution. The hosts which cannot be resolved are
  150. * deleted from the `inet_hosts' array.
  151. */
  152. void
  153. internet_hosts_to_ip(void)
  154. {
  155. int i;
  156. for (i = 0; i < server_opt.inet_hosts_counter; i++) {
  157. inet_prefix ip;
  158. if (andns_gethostbyname(server_opt.inet_hosts[i], &ip)) {
  159. error("Cannot resolve \"%s\". Check your netsukuku.conf",
  160. server_opt.inet_hosts[i]);
  161. /* remove the hname from `inet_hosts' */
  162. xfree(server_opt.inet_hosts[i]);
  163. server_opt.inet_hosts[i] =
  164. server_opt.inet_hosts[server_opt.inet_hosts_counter - 1];
  165. server_opt.inet_hosts_counter--;
  166. } else {
  167. xfree(server_opt.inet_hosts[i]);
  168. server_opt.inet_hosts[i] = xstrdup(inet_to_str(ip));
  169. }
  170. }
  171. }
  172. void
  173. init_igws(inet_gw *** igws, int **igws_counter, int levels)
  174. {
  175. *igws = xzalloc(sizeof(inet_gw *) * levels);
  176. if (igws_counter)
  177. *igws_counter = (int *) xzalloc(sizeof(int) * levels);
  178. }
  179. void
  180. reset_igws(inet_gw ** igws, int *igws_counter, int levels)
  181. {
  182. int i;
  183. if (!igws)
  184. return;
  185. for (i = 0; i < levels; i++) {
  186. if (igws[i])
  187. list_destroy(igws[i]);
  188. igws_counter[i] = 0;
  189. }
  190. }
  191. void
  192. free_igws(inet_gw ** igws, int *igws_counter, int levels)
  193. {
  194. if (!igws)
  195. return;
  196. reset_igws(igws, igws_counter, levels);
  197. if (igws)
  198. xfree(igws);
  199. if (igws_counter)
  200. xfree(igws_counter);
  201. }
  202. /*
  203. * init_my_igws
  204. *
  205. * initialiases the `my_igws' array. This list keeps inet_gw structs which
  206. * points to our (g)nodes, for example:
  207. * my_igws[0]->node == me.cur_node,
  208. * my_igws[1]->node == &me.cur_quadg.gnode[_EL(1)]->g,
  209. * ...
  210. */
  211. void
  212. init_my_igws(inet_gw ** igws, int *igws_counter,
  213. inet_gw *** my_new_igws, u_char my_bandwidth,
  214. map_node * cur_node, quadro_group * qg)
  215. {
  216. inet_gw *igw, **my_igws;
  217. map_node *node;
  218. int i = 0, e, bw_mean;
  219. init_igws(&my_igws, 0, qg->levels);
  220. for (i = 0; i < qg->levels; i++) {
  221. if (!i) {
  222. node = cur_node;
  223. bw_mean = my_bandwidth;
  224. } else {
  225. node = &qg->gnode[_EL(i)]->g;
  226. bw_mean = e = 0;
  227. igw = igws[i - 1];
  228. list_for(igw) {
  229. bw_mean += igw->bandwidth;
  230. e++;
  231. }
  232. bw_mean /= e;
  233. }
  234. igw = igw_add_node(igws, igws_counter, i, qg->gid[i],
  235. node, (int *) qg->ipstart[0].data,
  236. (u_char) bw_mean);
  237. my_igws[i] = igw;
  238. }
  239. *my_new_igws = my_igws;
  240. }
  241. void
  242. free_my_igws(inet_gw *** my_igs)
  243. {
  244. if (*my_igs && *my_igs)
  245. xfree(*my_igs);
  246. *my_igs = 0;
  247. }
  248. /*
  249. * init_internet_gateway_search:
  250. * Initialization of the igs.c code.
  251. */
  252. void
  253. init_internet_gateway_search(void)
  254. {
  255. inet_prefix new_gw;
  256. char new_gw_dev[IFNAMSIZ];
  257. pthread_t ping_thread;
  258. pthread_attr_t t_attr;
  259. int i, ret, res, e;
  260. active_gws = 0;
  261. igw_multi_gw_disabled = 0;
  262. setzero(multigw_nh, sizeof(igw_nexthop) * MAX_MULTIPATH_ROUTES);
  263. /*
  264. * Just return if we aren't in restricted mode or if the user doesn't
  265. * want to use shared internet connections
  266. */
  267. if (!restricted_mode || (!server_opt.use_shared_inet &&
  268. !server_opt.share_internet))
  269. return;
  270. loginfo("Activating the Internet Gateway Search engine");
  271. init_igws(&me.igws, &me.igws_counter, GET_LEVELS(my_family));
  272. init_tunnels_ifs();
  273. /* delete all the old tunnels */
  274. del_all_tunnel_ifs(0, 0, 0, NTK_TUNL_PREFIX);
  275. /*
  276. * Bring tunl0 up (just to test if the ipip module is loaded)
  277. */
  278. loginfo("Checking if \"" DEFAULT_TUNL_IF "\" exists");
  279. if (tunnel_change(0, 0, 0, DEFAULT_TUNL_PREFIX, DEFAULT_TUNL_NUMBER) <
  280. 0) {
  281. printf("Cannot read \"" DEFAULT_TUNL_IF "\". "
  282. "Is the \"ipip\" kernel module loaded?\n"
  283. " If you don't care about using the shared internet "
  284. "connections of the ntk nodes\n"
  285. " around you, disable the \"use_shared_inet\" option "
  286. "in netsukuku.conf");
  287. del_resolv_conf("nameserver 127.0.0.1", "/etc/resolv.conf");
  288. exit(1);
  289. }
  290. ifs_del_all_name(me.cur_ifs, &me.cur_ifs_n, NTK_TUNL_PREFIX);
  291. ifs_del_all_name(me.cur_ifs, &me.cur_ifs_n, DEFAULT_TUNL_PREFIX);
  292. /*
  293. * Delete old routing rules
  294. */
  295. reset_igw_rules();
  296. /*
  297. * Init netfilter
  298. */
  299. res = mark_init(server_opt.share_internet);
  300. if (res) {
  301. error(err_str);
  302. error("Cannot set the netfilter rules needed for the multi-igw. "
  303. "This feature will be disabled");
  304. igw_multi_gw_disabled = 1;
  305. }
  306. /*
  307. * Check anomalies: from this point we initialize stuff only if we
  308. * have an Inet connection
  309. */
  310. if (!server_opt.inet_connection)
  311. return;
  312. if (!server_opt.inet_hosts)
  313. fatal("You didn't specified any Internet hosts in the "
  314. "configuration file. What hosts should I ping?");
  315. /*
  316. * If we are sharing our internet connection, activate the
  317. * masquerading.
  318. */
  319. if (server_opt.share_internet) {
  320. igw_exec_masquerade_sh(server_opt.ip_masq_script, 0);
  321. if (!server_opt.ip_masq_script)
  322. fatal("No masquerading script was configured!");
  323. };
  324. /*
  325. * Get the default gateway route currently set in the kernel routing
  326. * table
  327. */
  328. setzero(&new_gw, sizeof(inet_prefix));
  329. ret = rt_get_default_gw(&new_gw, new_gw_dev);
  330. /*
  331. * If there is no IP set in the route, fetch it at least from the
  332. * device included in it.
  333. */
  334. if (!new_gw.family && *new_gw_dev) {
  335. if (get_dev_ip(&new_gw, my_family, new_gw_dev) < 0)
  336. (*new_gw_dev) = 0;
  337. }
  338. if (ret < 0 || (!*new_gw_dev && !new_gw.family)) {
  339. /* Nothing useful has been found */
  340. loginfo("The retrieval of the default gw from the kernel failed.");
  341. if (!server_opt.inet_gw.data[0])
  342. fatal("The default gw isn't set in the kernel and you "
  343. "didn't specified it in netsukuku.conf. "
  344. "Cannot continue!");
  345. } else if (!server_opt.inet_gw_dev ||
  346. strncmp(new_gw_dev, server_opt.inet_gw_dev, IFNAMSIZ) ||
  347. memcmp(new_gw.data, server_opt.inet_gw.data, MAX_IP_SZ)) {
  348. if (server_opt.inet_gw.data[0])
  349. loginfo("Your specified Internet gateway doesn't match with "
  350. "the one currently stored in the kernel routing table."
  351. "I'm going to use the kernel gateway: %s dev %s",
  352. inet_to_str(new_gw), new_gw_dev);
  353. if (!server_opt.inet_gw_dev)
  354. server_opt.inet_gw_dev = xstrdup(new_gw_dev);
  355. else
  356. strncpy(server_opt.inet_gw_dev, new_gw_dev, IFNAMSIZ);
  357. memcpy(&server_opt.inet_gw, &new_gw, sizeof(inet_prefix));
  358. /* Delete the default gw, we are replacing it */
  359. rt_delete_def_gw(0);
  360. }
  361. loginfo("Using \"%s dev %s\" as your first Internet gateway.",
  362. inet_to_str(server_opt.inet_gw), server_opt.inet_gw_dev);
  363. if (rt_replace_def_gw(server_opt.inet_gw_dev, server_opt.inet_gw, 0))
  364. fatal("Cannot set the default gw to %s %s",
  365. inet_to_str(server_opt.inet_gw), server_opt.inet_gw_dev);
  366. active_gws++;
  367. /*
  368. * Activate the anti-loop multi-igw shield
  369. */
  370. if (server_opt.share_internet) {
  371. rule_add(0, 0, 0, 0, FWMARK_ALISHIELD, RTTABLE_ALISHIELD);
  372. if (rt_replace_def_gw(server_opt.inet_gw_dev, server_opt.inet_gw,
  373. RTTABLE_ALISHIELD)) {
  374. error("Cannot set the default route in the ALISHIELD table. "
  375. "Disabling the multi-inet_gw feature");
  376. igw_multi_gw_disabled = 1;
  377. }
  378. }
  379. /*
  380. * Activate the traffic shaping for the `server_opt.inet_gw_dev'
  381. * device
  382. */
  383. if (server_opt.shape_internet)
  384. igw_exec_tcshaper_sh(server_opt.tc_shaper_script, 0,
  385. server_opt.inet_gw_dev,
  386. server_opt.my_upload_bw,
  387. server_opt.my_dnload_bw);
  388. for (i = 0; i < me.cur_ifs_n; i++)
  389. if (!strcmp(me.cur_ifs[i].dev_name, server_opt.inet_gw_dev)) {
  390. for (e = 0; e < server_opt.ifs_n; e++)
  391. if (!strcmp(server_opt.ifs[i], server_opt.inet_gw_dev))
  392. fatal("You specified the \"%s\" interface"
  393. " in the options, but this device is also"
  394. " part of the primary Internet gw route."
  395. " Don't include \"%s\" in the list of "
  396. "interfaces utilised by the daemon",
  397. server_opt.inet_gw_dev, server_opt.inet_gw_dev);
  398. loginfo("Deleting the \"%s\" interface from the device "
  399. "list since it is part of the primary Internet"
  400. " gw route.", me.cur_ifs[i].dev_name);
  401. ifs_del(me.cur_ifs, &me.cur_ifs_n, i);
  402. if (me.cur_ifs_n <= 0)
  403. fatal
  404. ("The deleted interface cannot be used by NetsukukuD because it is part\n"
  405. " of your primary Internet gw route. You have to specify another\n"
  406. " interface with the -i option or you won't be able share your"
  407. " Internet connection");
  408. }
  409. loginfo("Launching the first ping to the Internet hosts");
  410. if (!server_opt.disable_andna)
  411. internet_hosts_to_ip();
  412. me.inet_connected = igw_check_inet_conn();
  413. if (me.inet_connected)
  414. loginfo("The Internet connection is up & running");
  415. else
  416. loginfo("The Internet connection appears to be down");
  417. if (!me.inet_connected && server_opt.share_internet)
  418. fatal("We are not connected to the Internet, but you want to "
  419. "share your connection. Please check your options");
  420. debug(DBG_SOFT, "Evoking the Internet ping daemon.");
  421. pthread_attr_init(&t_attr);
  422. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  423. pthread_create(&ping_thread, &t_attr, igw_check_inet_conn_t, 0);
  424. }
  425. void
  426. close_internet_gateway_search(void)
  427. {
  428. if (!restricted_mode || (!server_opt.use_shared_inet &&
  429. !server_opt.share_internet))
  430. return;
  431. /* Flush the MASQUERADE rules */
  432. if (server_opt.share_internet)
  433. igw_exec_masquerade_sh(server_opt.ip_masq_script, 1);
  434. /* Disable the traffic shaping */
  435. if (server_opt.shape_internet)
  436. igw_exec_tcshaper_sh(server_opt.tc_shaper_script, 1,
  437. server_opt.inet_gw_dev, 0, 0);
  438. /* Delete all the added rules */
  439. reset_igw_rules();
  440. /* Destroy the netfilter rules */
  441. mark_close();
  442. /* Delete all the tunnels */
  443. del_all_tunnel_ifs(0, 0, 0, NTK_TUNL_PREFIX);
  444. free_igws(me.igws, me.igws_counter, me.cur_quadg.levels);
  445. free_my_igws(&me.my_igws);
  446. /* Free what has been malloced */
  447. free_internet_hosts(server_opt.inet_hosts,
  448. server_opt.inet_hosts_counter);
  449. }
  450. /*
  451. * igw_add_node: adds a new gw in the `igws[`level']' llist.
  452. * The pointer to the new inet_gw is returned.
  453. */
  454. inet_gw *
  455. igw_add_node(inet_gw ** igws, int *igws_counter, int level,
  456. int gid, map_node * node, int ip[MAX_IP_INT],
  457. u_char bandwidth)
  458. {
  459. inet_gw *igw;
  460. node->flags |= MAP_IGW;
  461. igw = xzalloc(sizeof(inet_gw));
  462. memcpy(igw->ip, ip, MAX_IP_SZ);
  463. igw->node = node;
  464. igw->gid = gid;
  465. igw->bandwidth = bandwidth;
  466. clist_add(&igws[level], &igws_counter[level], igw);
  467. return igw;
  468. }
  469. int
  470. igw_del(inet_gw ** igws, int *igws_counter, inet_gw * igw, int level)
  471. {
  472. if (!igw)
  473. return -1;
  474. igw->node->flags &= ~MAP_IGW;
  475. if (!igws[level])
  476. return -1;
  477. clist_del(&igws[level], &igws_counter[level], igw);
  478. return 0;
  479. }
  480. /*
  481. * igw_find_node: finds an inet_gw struct in the `igws[`level']' llist which
  482. * points to the given `node'. the pointer to the found struct is
  483. * returned, otherwise 0 is the return value.
  484. */
  485. inet_gw *
  486. igw_find_node(inet_gw ** igws, int level, map_node * node)
  487. {
  488. inet_gw *igw;
  489. igw = igws[level];
  490. list_for(igw)
  491. if (igw->node == node)
  492. return igw;
  493. return 0;
  494. }
  495. inet_gw *
  496. igw_find_ip(inet_gw ** igws, int level, u_int ip[MAX_IP_INT])
  497. {
  498. inet_gw *igw;
  499. igw = igws[level];
  500. list_for(igw)
  501. if (!memcmp(igw->ip, ip, MAX_IP_SZ))
  502. return igw;
  503. return 0;
  504. }
  505. /*
  506. * igw_del_node: deletes, from the `igws[`level']' llist, the inet_gw struct
  507. * which points to `node'. On success 0 is returned.
  508. */
  509. int
  510. igw_del_node(inet_gw ** igws, int *igws_counter, int level,
  511. map_node * node)
  512. {
  513. inet_gw *igw;
  514. igw = igw_find_node(igws, level, node);
  515. return igw_del(igws, igws_counter, igw, level);
  516. }
  517. /*
  518. * igw_update_gnode_bw:
  519. * call this function _after_ adding and _before_ deleting the `igw->node' node
  520. * from the me.igws llist. This fuctions will update the `bandwidth' value of
  521. * the inet_gw which points to our (g)nodes.
  522. * Use `new'=1 if you are adding the node, otherwise use 0.
  523. */
  524. void
  525. igw_update_gnode_bw(int *igws_counter, inet_gw ** my_igws, inet_gw * igw,
  526. int new, int level, int maxlevels)
  527. {
  528. int i, bw, old_bw = 0;
  529. if (level >= maxlevels)
  530. return;
  531. if (new) {
  532. if (igws_counter[level] <= 0)
  533. return;
  534. bw = my_igws[level + 1]->bandwidth * (igws_counter[level] - 1);
  535. bw = (bw + igw->bandwidth) / igws_counter[level];
  536. } else {
  537. if (igws_counter[level] <= 1)
  538. return;
  539. bw = my_igws[level + 1]->bandwidth * igws_counter[level];
  540. bw = (bw - igw->bandwidth) / (igws_counter[level] - 1);
  541. }
  542. old_bw = my_igws[level + 1]->bandwidth;
  543. my_igws[level + 1]->bandwidth = bw;
  544. for (i = level + 2; i < maxlevels; i++) {
  545. if (!my_igws[i] || igws_counter[i - 1] <= 0)
  546. break;
  547. bw = my_igws[i]->bandwidth * igws_counter[i - 1];
  548. bw = (bw - old_bw + my_igws[i - 1]->bandwidth) / igws_counter[i -
  549. 1];
  550. old_bw = my_igws[i]->bandwidth;
  551. my_igws[i]->bandwidth = bw;
  552. }
  553. }
  554. /*
  555. * igw_cmp: compares two inet_gw structs calculating their connection quality:
  556. * bandwith - rtt/1000;
  557. */
  558. int
  559. igw_cmp(const void *a, const void *b)
  560. {
  561. inet_gw *gw_a = *(inet_gw **) a;
  562. inet_gw *gw_b = *(inet_gw **) b;
  563. u_int cq_a, cq_b, trtt;
  564. /* let's calculate the connection quality of both A and B */
  565. trtt = gw_a->node->links ? gw_a->node->r_node[0].trtt / 1000 : 0;
  566. cq_a = bandwidth_to_32bit(gw_a->bandwidth) - trtt;
  567. trtt = gw_b->node->links ? gw_b->node->r_node[0].trtt / 1000 : 0;
  568. cq_b = bandwidth_to_32bit(gw_b->bandwidth) - trtt;
  569. if (cq_a > cq_b)
  570. return 1;
  571. else if (cq_a == cq_b)
  572. return 0;
  573. else
  574. return -1;
  575. }
  576. /*
  577. * igw_order: orders in decrescent order the `igws[`level']' llist,
  578. * comparing the igws[level]->bandwidth and igws[level]->node->r_node[0].trtt
  579. * values.
  580. * `my_igws[level]' will point to the inet_gw struct which refers to an our
  581. * (g)node.
  582. */
  583. void
  584. igw_order(inet_gw ** igws, int *igws_counter, inet_gw ** my_igws,
  585. int level)
  586. {
  587. inet_gw *igw, *new_head, *maxigws_ptr;
  588. int i;
  589. if (!igws_counter[level] || !igws[level])
  590. return;
  591. clist_qsort(new_head, igws[level], igws_counter[level], igw_cmp);
  592. igw = new_head;
  593. list_for(igw) {
  594. if (i >= MAXIGWS) {
  595. if (igw->node->flags & MAP_ME) {
  596. list_substitute(maxigws_ptr, igw);
  597. igw = maxigws_ptr;
  598. }
  599. /* The maximum number of igw has been exceeded */
  600. clist_del(&igws[level], &igws_counter[level], igw);
  601. }
  602. if (my_igws && igw->node->flags & MAP_ME)
  603. my_igws[level] = igw;
  604. if (i == MAXIGWS - 1)
  605. maxigws_ptr = igw;
  606. i++;
  607. }
  608. igws[level] = new_head;
  609. }
  610. /*
  611. * igw_check_inet_conn: returns 1 if we are still connected to the Internet.
  612. * The check is done by pinging the `server_opt.inet_hosts'.
  613. */
  614. int
  615. igw_check_inet_conn(void)
  616. {
  617. int i, ret;
  618. for (i = 0; server_opt.inet_hosts && server_opt.inet_hosts[i] &&
  619. i < server_opt.inet_hosts_counter; i++) {
  620. ret = pingthost(server_opt.inet_hosts[i], INET_HOST_PING_TIMEOUT);
  621. if (ret >= 1)
  622. return 1;
  623. }
  624. return 0;
  625. }
  626. /*
  627. * igw_check_inet_conn_t
  628. *
  629. * checks if we are connected to the internet, then waits, then checks
  630. * if we are connected, then ...
  631. */
  632. void *
  633. igw_check_inet_conn_t(void *null)
  634. {
  635. inet_prefix new_gw;
  636. char new_gw_dev[IFNAMSIZ];
  637. int old_status, ret;
  638. for (;;) {
  639. old_status = me.inet_connected;
  640. me.inet_connected = igw_check_inet_conn();
  641. if (old_status && !me.inet_connected) {
  642. /* Connection lost, disable me.my_igws[0] */
  643. loginfo
  644. ("Internet connection lost. Inet connection sharing disabled");
  645. me.my_igws[0]->bandwidth = 0;
  646. igw_update_gnode_bw(me.igws_counter, me.my_igws,
  647. me.my_igws[0], 0, 0, me.cur_quadg.levels);
  648. clist_join(&me.igws[0], &me.igws_counter[0], me.my_igws[0]);
  649. } else if (!old_status && me.inet_connected) {
  650. if (server_opt.share_internet) {
  651. /* Maybe the Internet gateway is changed, it's
  652. * better to check it */
  653. ret = rt_get_default_gw(&new_gw, new_gw_dev);
  654. if (ret < 0) {
  655. /*
  656. * Something's wrong, we can reach Inet
  657. * hosts, but we cannot take the default
  658. * gw, thus consider ourself not connected.
  659. */
  660. me.inet_connected = 0;
  661. goto skip_it;
  662. }
  663. if (strncmp(new_gw_dev, server_opt.inet_gw_dev, IFNAMSIZ)
  664. || memcmp(new_gw.data, server_opt.inet_gw.data,
  665. MAX_IP_SZ)) {
  666. /* New Internet gw (dialup connection ?) */
  667. strncpy(server_opt.inet_gw_dev, new_gw_dev, IFNAMSIZ);
  668. memcpy(&server_opt.inet_gw, &new_gw,
  669. sizeof(inet_prefix));
  670. loginfo
  671. ("Our Internet gateway changed, now it is: %s dev %s",
  672. inet_to_str(new_gw), new_gw_dev);
  673. } else
  674. loginfo("Internet connection is alive again. "
  675. "Inet connection sharing enabled");
  676. }
  677. /* Yay! We're connected, enable me.my_igws[0] */
  678. me.my_igws[0]->bandwidth = me.my_bandwidth;
  679. clist_ins(&me.igws[0], &me.igws_counter[0], me.my_igws[0]);
  680. igw_update_gnode_bw(me.igws_counter, me.my_igws,
  681. me.my_igws[0], 1, 0, me.cur_quadg.levels);
  682. }
  683. skip_it:
  684. sleep(INET_NEXT_PING_WAIT);
  685. }
  686. }
  687. /*
  688. * igw_ping_igw: pings `igw->ip' and returns 1 if it replies.
  689. */
  690. int
  691. igw_ping_igw(inet_gw * igw)
  692. {
  693. inet_prefix ip;
  694. char ntop[INET6_ADDRSTRLEN] = "\0";
  695. const char *ipstr;
  696. inet_setip_raw(&ip, igw->ip, my_family);
  697. if (!(ipstr = inet_to_str(ip)))
  698. return -1;
  699. strcpy(ntop, ipstr);
  700. return pingthost(ntop, IGW_HOST_PING_TIMEOUT) >= 1;
  701. }
  702. /*
  703. * igw_monitor_igws_t: it pings the Internet gateway which are currently
  704. * utilised in the kernel routing table and deletes the ones which don't
  705. * reply.
  706. */
  707. void *
  708. igw_monitor_igws_t(void *null)
  709. {
  710. inet_gw *igw, *next, *old_igw;
  711. int i, nexthops, ip[MAX_IP_INT], l, ni;
  712. nexthops = MAX_MULTIPATH_ROUTES / me.cur_quadg.levels;
  713. for (;;) {
  714. while (me.cur_node->flags & MAP_HNODE)
  715. sleep(1);
  716. for (i = 0; i < me.cur_quadg.levels; i++) {
  717. while (me.cur_node->flags & MAP_HNODE)
  718. sleep(1);
  719. igw = me.igws[i];
  720. ni = 0;
  721. list_safe_for(igw, next) {
  722. if (ni >= nexthops)
  723. break;
  724. if (!(igw->flags & IGW_ACTIVE))
  725. continue;
  726. if (!memcmp
  727. (igw->ip, me.cur_quadg.ipstart[0].data, MAX_IP_SZ))
  728. continue;
  729. if (!igw_ping_igw(igw)) {
  730. memcpy(ip, igw->ip, MAX_IP_SZ);
  731. loginfo("The Internet gw %s doesn't replies "
  732. "to pings. It is dead.",
  733. ipraw_to_str(igw->ip, my_family));
  734. for (l = i, old_igw = igw; l < me.cur_quadg.levels;
  735. l++) {
  736. igw_del(me.igws, me.igws_counter, old_igw, l);
  737. if (l + 1 < me.cur_quadg.levels)
  738. old_igw =
  739. igw_find_ip(me.igws, l + 1, (u_int *) ip);
  740. }
  741. igw_replace_def_igws(me.igws, me.igws_counter,
  742. me.my_igws, me.cur_quadg.levels,
  743. my_family);
  744. }
  745. ni++;
  746. }
  747. }
  748. sleep(INET_NEXT_PING_WAIT);
  749. }
  750. }
  751. /*
  752. * igw_exec_masquerade_sh: executes `script', which activate the IP masquerade.
  753. * If `stop' is set to 1 the script will be executed as "script stop",
  754. * otherwise as "script start".
  755. */
  756. int
  757. igw_exec_masquerade_sh(char *script, int stop)
  758. {
  759. int ret;
  760. char argv[7] = "";
  761. sprintf(argv, "%s", stop ? "stop" : "start");
  762. ret = exec_root_script(script, argv);
  763. if (ret == -1)
  764. fatal("%s wasn't executed. We cannot share the Inet "
  765. "connection, aborting.");
  766. return 0;
  767. }
  768. /*
  769. * igw_exec_tcshaper_sh: executes `script', which activate the Internet traffic
  770. * shaping.
  771. * If `stop' is set to 1 the script will be executed as "script stop `dev'".
  772. */
  773. int
  774. igw_exec_tcshaper_sh(char *script, int stop,
  775. char *dev, int upload_bw, int dnload_bw)
  776. {
  777. int ret;
  778. char argv[7] = "";
  779. if (stop)
  780. sprintf(argv, "%s %s", "stop", dev);
  781. else
  782. sprintf(argv, "%s %d %d", dev, upload_bw, dnload_bw);
  783. ret = exec_root_script(script, argv);
  784. if (ret == -1) {
  785. if (!stop)
  786. error("%s wasn't executed. The traffic shaping will be "
  787. "disabled.");
  788. else
  789. error("The traffic shaping is still enabled!");
  790. }
  791. return 0;
  792. }
  793. /*
  794. * add_igw_nexthop:
  795. *
  796. * `igwn' is an array of at leat MAX_MULTIPATH_ROUTES members.
  797. * `ip' is the ip of the nexthop
  798. *
  799. * add_igw_nexthop() searches `ip' in `igwn', if it is found the position in
  800. * the array of the igw_nexthop struct is returned, otherwise it adds `ip' in
  801. * the first empty member of the struct (its position is always returned).
  802. * In the first case `*new' is set to 0, in the second to 1.
  803. * If the array is full and nothing can be added -1 is returned.
  804. */
  805. int
  806. add_igw_nexthop(igw_nexthop * igwn, inet_prefix * ip, int *new)
  807. {
  808. int i;
  809. for (i = 0; i < MAX_MULTIPATH_ROUTES; i++)
  810. if (!memcmp(igwn[i].nexthop.data, ip->data, MAX_IP_SZ)) {
  811. igwn[i].flags |= IGW_ACTIVE;
  812. *new = 0;
  813. return i;
  814. }
  815. for (i = 0; i < MAX_MULTIPATH_ROUTES; i++) {
  816. if (!(igwn[i].flags & IGW_ACTIVE)) {
  817. inet_copy(&igwn[i].nexthop, ip);
  818. igwn[i].tunl = i;
  819. igwn[i].table = RTTABLE_IGW + i;
  820. igwn[i].flags |= IGW_ACTIVE;
  821. *new = 1;
  822. return i;
  823. }
  824. }
  825. *new = -1;
  826. return -1;
  827. }
  828. void
  829. set_igw_nexhtop_inactive(igw_nexthop * igwn)
  830. {
  831. int i;
  832. for (i = 0; i < MAX_MULTIPATH_ROUTES; i++)
  833. igwn[i].flags &= ~IGW_ACTIVE;
  834. }
  835. void
  836. reset_igw_nexthop(igw_nexthop * igwn)
  837. {
  838. setzero(igwn, sizeof(igw_nexthop) * MAX_MULTIPATH_ROUTES);
  839. }
  840. /*
  841. * reset_igw_rules: flush all the routing rules
  842. */
  843. void
  844. reset_igw_rules(void)
  845. {
  846. /*
  847. * Reset each rule added for a tunnel-nexthop
  848. * and the rule used for the Anti-loop multi-igw shield.
  849. */
  850. rule_flush_table_range(my_family, RTTABLE_IGW,
  851. RTTABLE_IGW + MAX_MULTIPATH_ROUTES);
  852. }
  853. /*
  854. * igw_replace_def_igws: sets the default gw route to reach the
  855. * Internet. The route utilises multipath therefore there are more than one
  856. * gateway which can be used to reach the Internet, these gateways are choosen
  857. * from the `igws' llist.
  858. * On error -1 is returned.
  859. */
  860. int
  861. igw_replace_def_igws(inet_gw ** igws, int *igws_counter,
  862. inet_gw ** my_igws, int max_levels, int family)
  863. {
  864. inet_gw *igw;
  865. inet_prefix to, ip;
  866. struct nexthop *nh = 0, nh_tmp[2];
  867. int ni, ni_lvl, nexthops, level, max_multipath_routes, i, x;
  868. int res, new_nexhtop;
  869. #ifdef DEBUG
  870. #define MAX_GW_IP_STR_SIZE (MAX_MULTIPATH_ROUTES*((INET6_ADDRSTRLEN+1)+IFNAMSIZ)+1)
  871. int n;
  872. char gw_ip[MAX_GW_IP_STR_SIZE] = "";
  873. #endif
  874. max_multipath_routes = MAX_MULTIPATH_ROUTES;
  875. /* to == 0.0.0.0 */
  876. inet_setip_anyaddr(&to, family);
  877. to.len = to.bits = 0;
  878. nh = xzalloc(sizeof(struct nexthop) * MAX_MULTIPATH_ROUTES);
  879. ni = 0; /* nexthop index */
  880. /*
  881. * If we are sharing our Internet connection use, as the primary
  882. * gateway `me.internet_gw'.
  883. */
  884. if (server_opt.share_internet && me.inet_connected) {
  885. memcpy(&nh[ni].gw, &server_opt.inet_gw, sizeof(inet_prefix));
  886. inet_htonl(nh[ni].gw.data, nh[ni].gw.family);
  887. nh[ni].dev = server_opt.inet_gw_dev;
  888. nh[ni].hops = 255 - ni;
  889. ni++;
  890. max_multipath_routes--;
  891. }
  892. /*
  893. * Set all our saved nexthop as inactives, then mark as "active" only
  894. * the nexhtop we are going to re-pick, in this way we can know what
  895. * nexthop have been dropped.
  896. */
  897. set_igw_nexhtop_inactive(multigw_nh);
  898. /* We choose an equal number of nexthops for each level */
  899. nexthops = max_multipath_routes / max_levels;
  900. for (level = 0; level < max_levels; level++) {
  901. /* Remember the nexthops we choose at each cycle */
  902. inet_gw *taken_nexthops[max_multipath_routes];
  903. #ifndef IGS_MULTI_GW
  904. if (ni)
  905. break;
  906. #else
  907. if (ni && igw_multi_gw_disabled)
  908. break;
  909. #endif
  910. /* Reorder igws[level] */
  911. igw_order(igws, igws_counter, my_igws, level);
  912. /*
  913. * Take the first `nexthops'# gateways and add them in `ni'
  914. */
  915. ni_lvl = 0;
  916. igw = igws[level];
  917. list_for(igw) {
  918. if (ni_lvl >= nexthops)
  919. break;
  920. /* Skip gateways which have a bandwidth too small */
  921. if (igw->bandwidth < MIN_CONN_BANDWIDTH)
  922. continue;
  923. /* Do not include ourself as an inet-gw */
  924. if (!memcmp(igw->ip, me.cur_ip.data, MAX_IP_SZ))
  925. continue;
  926. /* Avoid duplicates, do not choose gateways we already
  927. * included in the nexthops array */
  928. for (i = 0, x = 0; i < ni; i++)
  929. if (!memcmp(taken_nexthops[i]->ip, igw->ip, MAX_IP_SZ)) {
  930. x = 1;
  931. break;
  932. }
  933. if (x)
  934. continue;
  935. igw->flags |= IGW_ACTIVE;
  936. inet_setip(&nh[ni].gw, igw->ip, family);
  937. nh[ni].hops = max_multipath_routes - ni + 1;
  938. if ((x = add_igw_nexthop(multigw_nh, &nh[ni].gw,
  939. &new_nexhtop)) < 0)
  940. continue;
  941. nh[ni].dev = tunnel_ifs[multigw_nh[x].tunl].dev_name;
  942. /*
  943. * If we are reusing a tunnel of an old inet-gw,
  944. * delete it.
  945. */
  946. if (*nh[ni].dev && new_nexhtop)
  947. del_tunnel_if(0, 0, nh[ni].dev, NTK_TUNL_PREFIX,
  948. multigw_nh[x].tunl);
  949. if (!*nh[ni].dev) {
  950. setzero(&nh_tmp, sizeof(struct nexthop) * 2);
  951. memcpy(&nh_tmp[0], &nh[ni], sizeof(struct nexthop));
  952. inet_ntohl(nh_tmp[0].gw.data, nh_tmp[0].gw.family);
  953. /*
  954. * Initialize the `nh[ni].dev' tunnel, it's
  955. * its first time.
  956. */
  957. if ((add_tunnel_if(&nh_tmp[0].gw, &me.cur_ip, 0,
  958. NTK_TUNL_PREFIX, multigw_nh[x].tunl,
  959. &me.cur_ip)) < 0)
  960. continue;
  961. /*
  962. * Add the table for the new tunnel-gw:
  963. *
  964. * ip rule add from me.cur_ip \
  965. * fwmark multigw_nh[x].tunl+1 \
  966. * lookup multigw_nh[x].table
  967. */
  968. inet_copy(&ip, &me.cur_ip);
  969. if (multigw_nh[x].flags & IGW_RTRULE)
  970. rule_del(&ip, 0, 0, 0,
  971. multigw_nh[x].tunl, multigw_nh[x].table);
  972. inet_htonl(ip.data, ip.family);
  973. rule_add(&ip, 0, 0, 0, multigw_nh[x].tunl + 1,
  974. multigw_nh[x].table);
  975. multigw_nh[x].flags |= IGW_RTRULE;
  976. /*
  977. * Add the default route in the added table:
  978. *
  979. * ip route replace default via nh[ni].gw \
  980. * table multigw_nh[x].table \
  981. * dev nh[ni].dev
  982. */
  983. inet_htonl(nh_tmp[0].gw.data, nh_tmp[0].gw.family);
  984. if (route_replace
  985. (0, 0, 0, &to, nh_tmp, 0, multigw_nh[x].table))
  986. error("Cannote replace the default "
  987. "route of the table %d ", multigw_nh[x].table);
  988. res = create_mark_rules(multigw_nh[x].tunl + 1);
  989. if (res == -1)
  990. error(err_str);
  991. }
  992. taken_nexthops[ni] = igw;
  993. ni++;
  994. ni_lvl++;
  995. }
  996. if (ni_lvl >= nexthops)
  997. /* All the other gateways are inactive */
  998. list_for(igw)
  999. igw->flags &= ~IGW_ACTIVE;
  1000. }
  1001. nh[ni].dev = 0;
  1002. if (!ni && active_gws) {
  1003. #ifdef DEBUG
  1004. debug(DBG_INSANE, RED("igw_def_gw: no Internet gateways "
  1005. "available. Deleting the default route"));
  1006. #endif
  1007. rt_delete_def_gw(0);
  1008. active_gws = 0;
  1009. return 0;
  1010. } else if (!ni)
  1011. return 0;
  1012. #ifdef DEBUG
  1013. for (n = 0; nh && nh[n].dev; n++) {
  1014. strcat(gw_ip, inet_to_str(nh[n].gw));
  1015. strcat(gw_ip, "|");
  1016. strcat(gw_ip, nh[n].dev);
  1017. strcat(gw_ip, ":");
  1018. }
  1019. debug(DBG_INSANE, RED("igw_def_gw: default via %s"), gw_ip);
  1020. #endif
  1021. if (route_replace(0, 0, 0, &to, nh, 0, 0))
  1022. error("WARNING: Cannot update the default route " "lvl %d", level);
  1023. active_gws = ni;
  1024. return 0;
  1025. }
  1026. /*
  1027. * igw_build_bentry: It builds the Internet gateway bnode blocks to be added
  1028. * in the bnode's entry in the tracer pkt. For the specification of this type
  1029. * of bnode block read igs.h
  1030. *
  1031. * It returns the mallocated package containing the bblock, in `*pack_sz' it
  1032. * stores the package's size.
  1033. * The number of different bblock contained in the package is written in
  1034. * `*bblocks' if `bblocks' is not zero.
  1035. *
  1036. * On error it returns NULL.
  1037. */
  1038. char *
  1039. igw_build_bentry(u_char level, size_t * pack_sz, int *new_bblocks)
  1040. {
  1041. bnode_hdr *bhdr;
  1042. bnode_chunk *bchunk;
  1043. inet_gw *igws_buf[MAX_IGW_PER_QSPN_CHUNK], *igw;
  1044. inet_prefix ip;
  1045. int i, e, lvl, found_gws = 0, max_igws, gids[FAMILY_LVLS];
  1046. size_t total_bblocks_sz, bblock_sz;
  1047. char *bblock, *buf;
  1048. u_char *bnode_gid;
  1049. *pack_sz = 0;
  1050. if (new_bblocks)
  1051. *new_bblocks = 0;
  1052. ip.family = my_family;
  1053. /*
  1054. * Select the Internet gateways to be included in the bblock
  1055. */
  1056. max_igws = !level ? 1 : MAX_IGW_PER_QSPN_CHUNK;
  1057. if (!level && me.my_igws[level]->bandwidth)
  1058. igws_buf[found_gws++] = me.my_igws[level];
  1059. else {
  1060. for (lvl = level - 1, found_gws = 0;
  1061. lvl >= 0 && found_gws < max_igws; lvl--) {
  1062. igw = me.igws[lvl];
  1063. list_for(igw) {
  1064. igws_buf[found_gws++] = igw;
  1065. if (found_gws == max_igws)
  1066. break;
  1067. }
  1068. }
  1069. }
  1070. if (!found_gws)
  1071. /* nothing found */
  1072. return 0;
  1073. *new_bblocks = found_gws;
  1074. /*
  1075. * Create enough space for the bblock
  1076. */
  1077. bblock_sz = BNODEBLOCK_SZ(level + 1, 1);
  1078. total_bblocks_sz = bblock_sz * found_gws;
  1079. bblock = xzalloc(total_bblocks_sz);
  1080. /*
  1081. * Write each IGW in the bblock
  1082. */
  1083. for (i = 0, buf = (char *) bblock; i < found_gws; i++) {
  1084. bhdr = (bnode_hdr *) buf;
  1085. bhdr->bnode_levels = level + 1;
  1086. bhdr->links = 1;
  1087. bnode_gid = (u_char *) (buf + sizeof(bnode_hdr));
  1088. bchunk = (bnode_chunk *) ((char *) bnode_gid +
  1089. sizeof(u_char) * bhdr->bnode_levels);
  1090. /*
  1091. * Get the gids of `igw'
  1092. */
  1093. memcpy(ip.data, igws_buf[i]->ip, MAX_IP_SZ);
  1094. iptogids(&ip, gids, bhdr->bnode_levels);
  1095. for (e = 0; e < bhdr->bnode_levels; e++)
  1096. bnode_gid[e] = gids[e];
  1097. if (!i || igws_buf[i - 1]->ip[0] != igws_buf[i]->ip[0])
  1098. debug(DBG_INSANE, "igw_build_bentry: ip %s", inet_to_str(ip));
  1099. /* Fill the bnode chunk */
  1100. bchunk[0].gnode = 0;
  1101. bchunk[0].level = FAMILY_LVLS + 1;
  1102. bchunk[0].rtt = igws_buf[i]->bandwidth;
  1103. buf += bblock_sz;
  1104. }
  1105. *pack_sz = total_bblocks_sz;
  1106. return (char *) bblock;
  1107. }
  1108. /*
  1109. * igw_store_bblock
  1110. *
  1111. * It creates an inet_gw struct in me.igws using the bblock contained in
  1112. * `bchunk'. The hdr of the bblock is `bblock_hdr'.
  1113. * The bblock has been packed using igw_build_bentry().
  1114. * `level' is the level where the qspn_pkt which carries the bblock is being
  1115. * spread.
  1116. * The kernel routing table is also updated.
  1117. * On error -1 is returned.
  1118. */
  1119. int
  1120. igw_store_bblock(bnode_hdr * bblock_hdr, bnode_chunk * bchunk,
  1121. u_char level)
  1122. {
  1123. inet_prefix gw_ip;
  1124. map_node *node = 0;
  1125. map_gnode *gnode = 0;
  1126. inet_gw *igw;
  1127. int gids[me.cur_quadg.levels], ret = 0;
  1128. u_char *bnode_gid;
  1129. int i, update = 0;
  1130. /*
  1131. * Extract the IP of the Internet gateway
  1132. */
  1133. bnode_gid = (u_char *) bblock_hdr + sizeof(bnode_hdr);
  1134. for (i = 0; i < bblock_hdr->bnode_levels; i++)
  1135. gids[i] = bnode_gid[i];
  1136. for (; i < me.cur_quadg.levels; i++)
  1137. gids[i] = me.cur_quadg.gid[i];
  1138. gidtoipstart(gids, me.cur_quadg.levels, me.cur_quadg.levels, my_family,
  1139. &gw_ip);
  1140. #ifdef DEBUG
  1141. if (server_opt.dbg_lvl)
  1142. debug(DBG_NOISE,
  1143. GREEN("igw_store_bblock: storing %s IGW, level %d"),
  1144. inet_to_str(gw_ip), level);
  1145. #endif
  1146. /*
  1147. * Add `gw_ip' in all the levels >= `level' of me.igws
  1148. */
  1149. for (i = level; i < me.cur_quadg.levels; i++) {
  1150. if (!i)
  1151. node = node_from_pos(gids[i], me.int_map);
  1152. else {
  1153. gnode = gnode_from_pos(gids[i], me.ext_map[_EL(i)]);
  1154. node = &gnode->g;
  1155. }
  1156. igw = igw_find_ip(me.igws, i, gw_ip.data);
  1157. if (igw) {
  1158. if (abs(igw->bandwidth - (char) bchunk->rtt) >= IGW_BW_DELTA) {
  1159. igw->bandwidth = (char) bchunk->rtt;
  1160. update = 1;
  1161. }
  1162. } else {
  1163. igw_add_node(me.igws, me.igws_counter, i, gids[i], node,
  1164. (int *) gw_ip.data, bchunk->rtt);
  1165. update = 1;
  1166. }
  1167. }
  1168. if (!update)
  1169. /* we've finished */
  1170. return 0;
  1171. /*
  1172. * Refresh the Kernel routing table
  1173. */
  1174. ret = igw_replace_def_igws(me.igws, me.igws_counter, me.my_igws,
  1175. me.cur_quadg.levels, my_family);
  1176. if (ret == -1) {
  1177. debug(DBG_SOFT, ERROR_MSG "cannot replace default gateway",
  1178. ERROR_POS);
  1179. return -1;
  1180. }
  1181. return 0;
  1182. }
  1183. char *
  1184. pack_inet_gw(inet_gw * igw, char *pack)
  1185. {
  1186. char *buf;
  1187. buf = pack;
  1188. memcpy(buf, igw->ip, MAX_IP_SZ);
  1189. inet_htonl((u_int *) buf, my_family);
  1190. buf += MAX_IP_SZ;
  1191. memcpy(buf, &igw->gid, sizeof(u_char));
  1192. buf += sizeof(u_char);
  1193. memcpy(buf, &igw->bandwidth, sizeof(u_char));
  1194. buf += sizeof(u_char);
  1195. return pack;
  1196. }
  1197. inet_gw *
  1198. unpack_inet_gw(char *pack, inet_gw * igw)
  1199. {
  1200. char *buf = pack;
  1201. memcpy(igw->ip, buf, MAX_IP_SZ);
  1202. inet_ntohl(igw->ip, my_family);
  1203. buf += MAX_IP_SZ;
  1204. memcpy(&igw->gid, buf, sizeof(u_char));
  1205. buf += sizeof(u_char);
  1206. memcpy(&igw->bandwidth, buf, sizeof(u_char));
  1207. buf += sizeof(u_char);
  1208. return igw;
  1209. }
  1210. /*
  1211. * pack_igws: it packs the each `igws[`level']' llist and sets the package size
  1212. * in `pack_sz'. The package is returned, otherwise, on error, NULL is the
  1213. * value returned.
  1214. */
  1215. char *
  1216. pack_igws(inet_gw ** igws, int *igws_counter, int levels, int *pack_sz)
  1217. {
  1218. struct inet_gw_pack_hdr hdr;
  1219. inet_gw *igw;
  1220. int lvl;
  1221. char *pack, *buf;
  1222. setzero(&hdr, sizeof(struct inet_gw_pack_hdr));
  1223. /*
  1224. * Fill the pack header and calculate the total pack size
  1225. */
  1226. hdr.levels = levels;
  1227. *pack_sz = sizeof(struct inet_gw_pack_hdr);
  1228. for (lvl = 0; lvl < levels; lvl++) {
  1229. hdr.gws[lvl] = igws_counter[lvl];
  1230. (*pack_sz) += hdr.gws[lvl] * INET_GW_PACK_SZ;
  1231. }
  1232. buf = pack = xzalloc(*pack_sz);
  1233. memcpy(buf, &hdr, sizeof(struct inet_gw_pack_hdr));
  1234. ints_host_to_network(buf, inet_gw_pack_hdr_iinfo);
  1235. buf += sizeof(struct inet_gw_pack_hdr);
  1236. /* Pack `igws' */
  1237. for (lvl = 0; lvl < levels; lvl++) {
  1238. igw = igws[lvl];
  1239. list_for(igw) {
  1240. pack_inet_gw(igw, buf);
  1241. buf += INET_GW_PACK_SZ;
  1242. }
  1243. }
  1244. return pack;
  1245. }
  1246. /*
  1247. * unpack_igws: upacks what pack_igws() packed.
  1248. * `pack' is the package which is `pack_sz' big.
  1249. * The pointer to the unpacked igws are stored in `new_igws' and
  1250. * `new_igws_counter'.
  1251. * On error -1 is returned.
  1252. */
  1253. int
  1254. unpack_igws(char *pack, size_t pack_sz,
  1255. map_node * int_map, map_gnode ** ext_map, int levels,
  1256. inet_gw *** new_igws, int **new_igws_counter)
  1257. {
  1258. struct inet_gw_pack_hdr *hdr;
  1259. inet_gw *igw, **igws;
  1260. size_t sz;
  1261. int i, lvl = 0, *igws_counter;
  1262. char *buf;
  1263. hdr = (struct inet_gw_pack_hdr *) pack;
  1264. ints_network_to_host(hdr, inet_gw_pack_hdr_iinfo);
  1265. sz = IGWS_PACK_SZ(hdr);
  1266. /* Verify the package header */
  1267. if (sz != pack_sz || sz > MAX_IGWS_PACK_SZ(levels) ||
  1268. hdr->levels > levels) {
  1269. debug(DBG_NORMAL, "Malformed igws package");
  1270. return -1;
  1271. }
  1272. init_igws(&igws, &igws_counter, levels);
  1273. buf = pack + sizeof(struct inet_gw_pack_hdr);
  1274. for (lvl = 0; lvl < hdr->levels; lvl++) {
  1275. for (i = 0; i < hdr->gws[lvl]; i++) {
  1276. igw = xzalloc(sizeof(inet_gw));
  1277. unpack_inet_gw(buf, igw);
  1278. igw->node = node_from_pos(igw->gid, int_map);
  1279. clist_add(&igws[lvl], &igws_counter[lvl], igw);
  1280. buf += INET_GW_PACK_SZ;
  1281. }
  1282. }
  1283. *new_igws = igws;
  1284. *new_igws_counter = igws_counter;
  1285. return 0;
  1286. }