No Description

001-always-resolve-ips.patch 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. diff --git a/cstp.c b/cstp.c
  2. index b1235ef..f955b82 100644
  3. --- a/cstp.c
  4. +++ b/cstp.c
  5. @@ -570,7 +570,10 @@ int openconnect_make_cstp_connection(struct openconnect_info *vpninfo)
  6. return ret;
  7. }
  8. -static int cstp_reconnect(struct openconnect_info *vpninfo)
  9. +/* When dead peer is set, this function will re-attempt resolving
  10. + * the peer in case its IP changed.
  11. + */
  12. +static int cstp_reconnect(struct openconnect_info *vpninfo, unsigned dead_peer)
  13. {
  14. int ret;
  15. int timeout;
  16. @@ -591,6 +594,16 @@ static int cstp_reconnect(struct openconnect_info *vpninfo)
  17. timeout = vpninfo->reconnect_timeout;
  18. interval = vpninfo->reconnect_interval;
  19. + /* handle cases with dynamic DNS by forcing a new resolve.
  20. + * The original IP is saved to retry as fallback if resolving
  21. + * fails.
  22. + */
  23. + if (dead_peer && vpninfo->first_peer_addr == NULL) {
  24. + vpninfo->first_peer_addr = vpninfo->peer_addr;
  25. + vpninfo->first_peer_addrlen = vpninfo->peer_addrlen;
  26. + vpninfo->peer_addr = NULL;
  27. + }
  28. +
  29. while ((ret = openconnect_make_cstp_connection(vpninfo))) {
  30. if (timeout <= 0)
  31. return ret;
  32. @@ -611,6 +624,11 @@ static int cstp_reconnect(struct openconnect_info *vpninfo)
  33. interval += vpninfo->reconnect_interval;
  34. if (interval > RECONNECT_INTERVAL_MAX)
  35. interval = RECONNECT_INTERVAL_MAX;
  36. +
  37. + if (dead_peer && vpninfo->first_peer_addr != NULL) {
  38. + free(vpninfo->peer_addr);
  39. + vpninfo->peer_addr = NULL;
  40. + }
  41. }
  42. script_config_tun(vpninfo, "reconnect");
  43. return 0;
  44. @@ -903,8 +921,15 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
  45. /* Not that this will ever happen; we don't even process
  46. the setting when we're asked for it. */
  47. vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n"));
  48. - if (vpninfo->ssl_times.rekey_method == REKEY_TUNNEL)
  49. - goto do_reconnect;
  50. + if (vpninfo->ssl_times.rekey_method == REKEY_TUNNEL) {
  51. + ret = cstp_reconnect(vpninfo, 0);
  52. + if (ret) {
  53. + vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
  54. + vpninfo->quit_reason = "CSTP reconnect failed";
  55. + return ret;
  56. + }
  57. + goto do_dtls_reconnect;
  58. + }
  59. else if (vpninfo->ssl_times.rekey_method == REKEY_SSL) {
  60. ret = cstp_handshake(vpninfo, 0);
  61. if (ret) {
  62. @@ -922,7 +947,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
  63. vpn_progress(vpninfo, PRG_ERR,
  64. _("CSTP Dead Peer Detection detected dead peer!\n"));
  65. do_reconnect:
  66. - ret = cstp_reconnect(vpninfo);
  67. + ret = cstp_reconnect(vpninfo, 1);
  68. if (ret) {
  69. vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
  70. vpninfo->quit_reason = "CSTP reconnect failed";
  71. diff --git a/library.c b/library.c
  72. index f5d3dc9..7c8d5ec 100644
  73. --- a/library.c
  74. +++ b/library.c
  75. @@ -178,6 +178,7 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo)
  76. CloseHandle(vpninfo->dtls_event);
  77. #endif
  78. free(vpninfo->peer_addr);
  79. + free(vpninfo->first_peer_addr);
  80. free_optlist(vpninfo->csd_env);
  81. free_optlist(vpninfo->script_env);
  82. free_optlist(vpninfo->cookies);
  83. @@ -291,6 +292,8 @@ int openconnect_set_hostname(struct openconnect_info *vpninfo,
  84. vpninfo->unique_hostname = NULL;
  85. free(vpninfo->peer_addr);
  86. vpninfo->peer_addr = NULL;
  87. + free(vpninfo->first_peer_addr);
  88. + vpninfo->first_peer_addr = NULL;
  89. return 0;
  90. }
  91. diff --git a/openconnect-internal.h b/openconnect-internal.h
  92. index 1bc79e5..cafbb3c 100644
  93. --- a/openconnect-internal.h
  94. +++ b/openconnect-internal.h
  95. @@ -424,6 +424,9 @@ struct openconnect_info {
  96. struct sockaddr *peer_addr;
  97. struct sockaddr *dtls_addr;
  98. + struct sockaddr *first_peer_addr;
  99. + socklen_t first_peer_addrlen;
  100. +
  101. int dtls_local_port;
  102. int deflate;
  103. diff --git a/ssl.c b/ssl.c
  104. index b50652d..e341871 100644
  105. --- a/ssl.c
  106. +++ b/ssl.c
  107. @@ -110,6 +110,7 @@ int connect_https_socket(struct openconnect_info *vpninfo)
  108. {
  109. int ssl_sock = -1;
  110. int err;
  111. + unsigned retry_old_ip = 0;
  112. if (!vpninfo->port)
  113. vpninfo->port = 443;
  114. @@ -230,6 +231,8 @@ int connect_https_socket(struct openconnect_info *vpninfo)
  115. if (hints.ai_flags & AI_NUMERICHOST)
  116. free(hostname);
  117. ssl_sock = -EINVAL;
  118. + if (vpninfo->first_peer_addr != NULL)
  119. + retry_old_ip = 1;
  120. goto out;
  121. }
  122. if (hints.ai_flags & AI_NUMERICHOST)
  123. @@ -291,7 +294,10 @@ int connect_https_socket(struct openconnect_info *vpninfo)
  124. }
  125. freeaddrinfo(result);
  126. +
  127. if (ssl_sock < 0) {
  128. + if (vpninfo->first_peer_addr != NULL)
  129. + retry_old_ip = 1;
  130. vpn_progress(vpninfo, PRG_ERR,
  131. _("Failed to connect to host %s\n"),
  132. vpninfo->proxy?:vpninfo->hostname);
  133. @@ -314,6 +320,21 @@ int connect_https_socket(struct openconnect_info *vpninfo)
  134. }
  135. }
  136. out:
  137. + if (retry_old_ip != 0 && vpninfo->first_peer_addr != NULL) {
  138. + vpn_progress(vpninfo, PRG_ERR,
  139. + _("Retrying connection to host %s with original IP\n"),
  140. + vpninfo->proxy?:vpninfo->hostname);
  141. +
  142. + retry_old_ip = 0;
  143. + if (vpninfo->first_peer_addrlen > vpninfo->peer_addrlen || vpninfo->peer_addr == NULL)
  144. + realloc_inplace(vpninfo->peer_addr, vpninfo->first_peer_addrlen);
  145. +
  146. + if (vpninfo->peer_addr != NULL) {
  147. + memcpy(vpninfo->peer_addr, vpninfo->first_peer_addr, vpninfo->first_peer_addrlen);
  148. + goto reconnect;
  149. + }
  150. + }
  151. +
  152. /* If proxy processing returned -EAGAIN to reconnect before attempting
  153. further auth, and we failed to reconnect, we have to clean up here. */
  154. cleanup_proxy_auth(vpninfo);