/* this odd do-hickey is to share error reporting code. 【程序编程相关:[转]浅谈如何学习linux v1.2】
【推荐阅读:[转]通过PXE远程安装linux】 * a break will get to that common code. the setting 【扩展信息:wget好像不支持断点续传】 * of "ugh" and "context" parameterize it. */ do { /* old entries have no packet count; new ones do. * check if things are as they should be. */ if (fi == 5) ff = &field[0]; /* old form, with no count */ else if (fi == 6) ff = &field[1]; /* new form, with count */ else { ugh = "has wrong number of fields"; break; } if (ff[1].len != 2 || strncmp(ff[1].ptr, "->", 2) != 0 || ff[3].len != 2 || strncmp(ff[3].ptr, "=>", 2) != 0) { ugh = "is missing -> or =>"; break; } /* actually digest fields of interest */ /* packet count */ eri.count = 0; if (ff != field) { context = "count field is malformed: "; ugh = ttoul(field[0].ptr, field[0].len, 10, &eri.count); if (ugh != null) break; } /* our client */ context = "source subnet field malformed: "; ugh = ttosubnet(ff[0].ptr, ff[0].len, af_inet, &eri.ours); if (ugh != null) break; /* his client */ context = "source subnet field malformed: "; ugh = ttosubnet(ff[2].ptr, ff[2].len, af_inet, &eri.his); if (ugh != null) break; /* said */ context = "sa id field malformed: "; ugh = ttosa(ff[4].ptr, ff[4].len, &eri.said); } while (false); if (ugh != null) { log("internal error: %s line %d %s%s" , procname, lino, context, ugh); continue; /* ignore rest of line */ } /* now we have decoded eroute, lets consider it. * we only care about shunt eroutes. * * %hold: if not known, add to orphaned_holds list for initiation * because acquire might have been lost. * * %pass: determine if idle; if so, blast it away. * can occur bare (if dns provided insufficient information) * or with a connection (failure context). * could even be installed by ipsec manual. * * %trap: always welcome. * * others: handling as yet undesigned. generally associated * with a failure context. */ if (eri.said.proto == sa_int) { switch (ntohl(eri.said.spi)) { case spi_hold: if (bare_shunt_ptr(&eri.ours, &eri.his) == null && shunt_owner(&eri.ours, &eri.his) == null) { eri.next = orphaned_holds; orphaned_holds = clone_thing(eri, "orphaned %hold"); } break; case spi_pass: /* nothing sensible to do if we dont have counts */ if (ff != field) { struct bare_shunt **bs_pp = bare_shunt_ptr(&eri.ours, &eri.his); if (bs_pp != null) { struct bare_shunt *bs = *bs_pp; if (eri.count != bs->count) { bs->count = eri.count; bs->last_activity = nw; } else if (nw - bs->last_activity > shunt_patience) { eri.next = expired; expired = clone_thing(eri, "expired %pass"); } } } break; case spi_drop: case spi_reject: case spi_trap: break; default: impossible(); } } } /* for each line */ fclose(f); /* now that weve finished processing the /proc file, * it is safe to delete the expired %pass shunts. */ ... 下一页