32_all_pado-timeout.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. --- ppp-2.4.6/pppd/plugins/rp-pppoe/discovery.c
  2. +++ ppp-2.4.6/pppd/plugins/rp-pppoe/discovery.c
  3. @@ -39,6 +39,7 @@
  4. #endif
  5. #include <signal.h>
  6. +#include <time.h>
  7. /* Calculate time remaining until *exp, return 0 if now >= *exp */
  8. static int time_left(struct timeval *diff, struct timeval *exp)
  9. @@ -251,6 +252,80 @@
  10. }
  11. /***********************************************************************
  12. +*%FUNCTION: recvPacketForMe
  13. +*%ARGUMENTS:
  14. +* packet -- output parameter
  15. +* len -- output parameter length
  16. +* conn -- connection
  17. +* start -- operation startup timestamp
  18. +* timeout -- how long to wait (in seconds)
  19. +*%RETURNS:
  20. +* -1: error
  21. +* 0: timed out
  22. +* 1: packet received
  23. +*%DESCRIPTION:
  24. +* receive and filter junk packets
  25. +***********************************************************************/
  26. +
  27. +static int
  28. +recvPacketForMe(PPPoEPacket *packet, int *len, PPPoEConnection *conn, time_t start, int timeout)
  29. +{
  30. + fd_set readable;
  31. + int r;
  32. + struct timeval tv;
  33. + time_t now;
  34. + int time_remain;
  35. +
  36. + do {
  37. + time(&now);
  38. + time_remain = timeout - (int)difftime(now, start);
  39. + if (time_remain <= 0) return 0; /* Timed out */
  40. +
  41. + if (BPF_BUFFER_IS_EMPTY) {
  42. + tv.tv_sec = time_remain;
  43. + tv.tv_usec = 0;
  44. +
  45. + FD_ZERO(&readable);
  46. + FD_SET(conn->discoverySocket, &readable);
  47. +
  48. + r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
  49. + if (r < 0)
  50. + {
  51. + if (errno == EINTR)
  52. + {
  53. + continue; /* interrupted, so retry */
  54. + }else
  55. + {
  56. + error("pppoe: recvPacketForMe: select: %m");
  57. + return -1;
  58. + }
  59. + }
  60. +
  61. + if (r == 0) return 0; /* Timed out */
  62. + }
  63. +
  64. + /* Get the packet */
  65. + receivePacket(conn->discoverySocket, packet, len);
  66. +
  67. + /* Check length */
  68. + if (ntohs(packet->length) + HDR_SIZE > *len) {
  69. + error("Bogus PPPoE length field (%u)",
  70. + (unsigned int) ntohs(packet->length));
  71. + continue;
  72. + }
  73. +
  74. +#ifdef USE_BPF
  75. + /* If it's not a Discovery packet, loop again */
  76. + if (etherType(&packet) != Eth_PPPOE_Discovery) continue;
  77. +#endif
  78. + /* If it's not for us, loop again */
  79. + }while ( ! packetIsForMe(conn, packet));
  80. +
  81. + return 1;
  82. +}
  83. +
  84. +
  85. +/***********************************************************************
  86. *%FUNCTION: sendPADI
  87. *%ARGUMENTS:
  88. * conn -- PPPoEConnection structure
  89. @@ -344,13 +419,12 @@
  90. void
  91. waitForPADO(PPPoEConnection *conn, int timeout)
  92. {
  93. - fd_set readable;
  94. int r;
  95. - struct timeval tv;
  96. struct timeval expire_at;
  97. PPPoEPacket packet;
  98. int len;
  99. + time_t start;
  100. struct PacketCriteria pc;
  101. pc.conn = conn;
  102. @@ -367,43 +441,10 @@
  103. }
  104. expire_at.tv_sec += timeout;
  105. + time(&start);
  106. do {
  107. - if (BPF_BUFFER_IS_EMPTY) {
  108. - if (!time_left(&tv, &expire_at))
  109. - return; /* Timed out */
  110. -
  111. - FD_ZERO(&readable);
  112. - FD_SET(conn->discoverySocket, &readable);
  113. -
  114. - while(1) {
  115. - r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
  116. - if (r >= 0 || errno != EINTR) break;
  117. - }
  118. - if (r < 0) {
  119. - error("select (waitForPADO): %m");
  120. - return;
  121. - }
  122. - if (r == 0)
  123. - return; /* Timed out */
  124. - }
  125. -
  126. - /* Get the packet */
  127. - receivePacket(conn->discoverySocket, &packet, &len);
  128. -
  129. - /* Check length */
  130. - if (ntohs(packet.length) + HDR_SIZE > len) {
  131. - error("Bogus PPPoE length field (%u)",
  132. - (unsigned int) ntohs(packet.length));
  133. - continue;
  134. - }
  135. -
  136. -#ifdef USE_BPF
  137. - /* If it's not a Discovery packet, loop again */
  138. - if (etherType(&packet) != Eth_PPPOE_Discovery) continue;
  139. -#endif
  140. -
  141. - /* If it's not for us, loop again */
  142. - if (!packetIsForMe(conn, &packet)) continue;
  143. + r = recvPacketForMe(&packet, &len, conn, start, timeout);
  144. + if (r<=0) return; /* Timed out or error */
  145. if (packet.code == CODE_PADO) {
  146. if (NOT_UNICAST(packet.ethHdr.h_source)) {
  147. @@ -537,13 +578,12 @@
  148. static void
  149. waitForPADS(PPPoEConnection *conn, int timeout)
  150. {
  151. - fd_set readable;
  152. int r;
  153. - struct timeval tv;
  154. struct timeval expire_at;
  155. PPPoEPacket packet;
  156. int len;
  157. + time_t start;
  158. if (gettimeofday(&expire_at, NULL) < 0) {
  159. error("gettimeofday (waitForPADS): %m");
  160. @@ -551,48 +591,15 @@
  161. }
  162. expire_at.tv_sec += timeout;
  163. + time(&start);
  164. conn->error = 0;
  165. do {
  166. - if (BPF_BUFFER_IS_EMPTY) {
  167. - if (!time_left(&tv, &expire_at))
  168. - return; /* Timed out */
  169. -
  170. - FD_ZERO(&readable);
  171. - FD_SET(conn->discoverySocket, &readable);
  172. -
  173. - while(1) {
  174. - r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
  175. - if (r >= 0 || errno != EINTR) break;
  176. - }
  177. - if (r < 0) {
  178. - error("select (waitForPADS): %m");
  179. - return;
  180. - }
  181. - if (r == 0)
  182. - return; /* Timed out */
  183. - }
  184. -
  185. - /* Get the packet */
  186. - receivePacket(conn->discoverySocket, &packet, &len);
  187. -
  188. - /* Check length */
  189. - if (ntohs(packet.length) + HDR_SIZE > len) {
  190. - error("Bogus PPPoE length field (%u)",
  191. - (unsigned int) ntohs(packet.length));
  192. - continue;
  193. - }
  194. -
  195. -#ifdef USE_BPF
  196. - /* If it's not a Discovery packet, loop again */
  197. - if (etherType(&packet) != Eth_PPPOE_Discovery) continue;
  198. -#endif
  199. + r = recvPacketForMe(&packet, &len, conn, start, timeout);
  200. + if (r<=0) return; /* Timed out or error */
  201. /* If it's not from the AC, it's not for me */
  202. if (memcmp(packet.ethHdr.h_source, conn->peerEth, ETH_ALEN)) continue;
  203. - /* If it's not for us, loop again */
  204. - if (!packetIsForMe(conn, &packet)) continue;
  205. -
  206. /* Is it PADS? */
  207. if (packet.code == CODE_PADS) {
  208. /* Parse for goodies */
  209. --- ppp-2.4.6/pppd/plugins/rp-pppoe/pppoe-discovery.c
  210. +++ ppp-2.4.6/pppd/plugins/rp-pppoe/pppoe-discovery.c
  211. @@ -14,6 +14,7 @@
  212. #include <unistd.h>
  213. #include <errno.h>
  214. #include <string.h>
  215. +#include <time.h>
  216. #include "pppoe.h"
  217. @@ -513,6 +514,8 @@
  218. struct timeval tv;
  219. PPPoEPacket packet;
  220. int len;
  221. + time_t start, now;
  222. + int time_remain;
  223. struct PacketCriteria pc;
  224. pc.conn = conn;
  225. @@ -522,9 +525,13 @@
  226. pc.seenServiceName = 0;
  227. conn->error = 0;
  228. + time(&start);
  229. do {
  230. + time(&now);
  231. + time_remain = timeout - (int)difftime(now, start);
  232. + if (time_remain <= 0) return; /* Timed out */
  233. if (BPF_BUFFER_IS_EMPTY) {
  234. - tv.tv_sec = timeout;
  235. + tv.tv_sec = time_remain;
  236. tv.tv_usec = 0;
  237. FD_ZERO(&readable);