Guest User

Untitled

a guest
Jun 20th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1. Index: repy/repy_constants.py
  2. ===================================================================
  3. --- repy/repy_constants.py (revision 2326)
  4. +++ repy/repy_constants.py (working copy)
  5. @@ -32,3 +32,14 @@
  6. CPU_POLLING_FREQ_LINUX = .1 # Linux
  7. CPU_POLLING_FREQ_WIN = .1 # Windows
  8. CPU_POLLING_FREQ_WINCE = .5 # Mobile devices are pretty slow
  9. +
  10. +
  11. +# These IP addresses are used to resolve our external IP address
  12. +# We attempt to connect to these IP addresses, and then check our local IP
  13. +# These addresses were choosen since they have been historically very stable
  14. +# They are from public universities
  15. +STABLE_PUBLIC_IPS = ["18.7.22.69", # M.I.T
  16. + "171.67.216.8", # Stanford
  17. + "169.229.131.81", # Berkley
  18. + "140.142.12.202"] # Univ. of Washington
  19. +
  20. Index: repy/emulcomm.py
  21. ===================================================================
  22. --- repy/emulcomm.py (revision 2326)
  23. +++ repy/emulcomm.py (working copy)
  24. @@ -37,6 +37,9 @@
  25. # Armon: Used for decoding the error messages
  26. import errno
  27.  
  28. +# Armon: Used for getting the constant IP values for resolving our external IP
  29. +import repy_constants
  30. +
  31. # The architecture is that I have a thread which "polls" all of the sockets
  32. # that are being listened on using select. If a connection
  33. # oriented socket has a connection pending, or a message-based socket has a
  34. @@ -711,56 +714,79 @@
  35. # Return the first allowed ip, there is always at least 1 element (loopback)
  36. return allowediplist[0]
  37.  
  38. - # Open a connectionless socket
  39. - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  40. + # Store the last exception object, if we fail before any socket related exception
  41. + # it must be due to a lack of a stable IP to use
  42. + exceptionobj = "No available external IP!"
  43. +
  44. + # Initialize these to None, so we can detect a failure
  45. + myip = None
  46. +
  47. + # It's possible on some platforms (Windows Mobile) that the IP will be
  48. + # 0.0.0.0 even when I have a public IP and the external IP is up. However, if
  49. + # I get a real connection with SOCK_STREAM, then I should get the real
  50. + # answer.
  51. + for conn_type in [socket.SOCK_DGRAM, socket.SOCK_STREAM]:
  52. +
  53. + # Try each stable IP
  54. + for ip_addr in repy_constants.STABLE_PUBLIC_IPS:
  55. + try:
  56. + # Try to resolve using the current connection type and
  57. + # stable IP, using port 80 since some platforms panic
  58. + # when given 0 (FreeBSD)
  59. + myip = resolve_local_ip(conn_type, ip_addr, 80)
  60. + except Exception, e:
  61. + exceptionobj = e
  62. + else:
  63. + # Return immediately if the IP address is good
  64. + if myip != None and myip != '' and myip != "0.0.0.0":
  65. + return myip
  66.  
  67. - # Tell it to connect to google (we assume that the DNS entry for this works)
  68. - # however, using port 0 causes some issues on FreeBSD! I choose port 80
  69. - # instead...
  70. - try:
  71. - s.connect(('google.com', 80))
  72. - except Exception, e:
  73. - # I reraise the exception from here because exceptions raised by connect
  74. - # are treated as "from a string" which confuses the traceback printer
  75. - # unless I re-raise it here (then it lists my line which is culled)
  76. - raise e
  77.  
  78. - # and the IP of the interface this connects on is the first item of the tuple
  79. - (myip, localport) = s.getsockname()
  80. + # Since we haven't returned yet, we must have failed.
  81. + # Raise an exception
  82. + raise Exception, "Cannot get external IP. Last exception: "+str(message)
  83. +
  84. +
  85. +
  86. +def resolve_local_ip(connection_type, external_ip, external_port=80):
  87. + """
  88. + <Purpose>
  89. + Resolve the local ip used when connecting outbound to an external ip.
  90.  
  91. - s.close()
  92. + <Arguments>
  93. + connection_type:
  94. + The type of connection to attempt. See socket.socket().
  95. +
  96. + external_ip:
  97. + The external IP to attempt to connect to.
  98. +
  99. + external_port:
  100. + The port on the remote host to attempt to connect to.
  101. +
  102. + <Exceptions>
  103. + As with socket.socket(), socketobj.connect(), etc.
  104. +
  105. + <Returns>
  106. + The locally assigned IP for the connection.
  107. + """
  108. + # Open a socket
  109. + s = socket.socket(socket.AF_INET, connection_type)
  110.  
  111. + try:
  112. + s.connect((external_ip, external_port))
  113.  
  114. - if myip == '' or myip == '0.0.0.0':
  115. - # It's possible on some platforms (Windows Mobile) that the IP will be
  116. - # 0.0.0.0 even when I have a public IP and google is up. However, if
  117. - # I get a real connection with SOCK_STREAM, then I should get the real
  118. - # answer.
  119. - # I'll do much the same as before, only using SOCK_STREAM, which
  120. - # unfortunately will actually connect
  121. - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  122. - try:
  123. - s.connect(('google.com', 80))
  124. - except Exception, e:
  125. - raise e
  126. - (myip, localport) = s.getsockname()
  127. -
  128. + # Get the local connection information for this socket
  129. + (myip, localport) = s.getsockname()
  130. +
  131. + # Always close the socket
  132. + finally:
  133. s.close()
  134. -
  135. - if myip == '' or myip == '0.0.0.0':
  136. - # hmm, SOCK_STREAM failed too. Let's raise an exception...
  137. - raise Exception, "Cannot get external IP despite successful name resolution. Sockets do not seem to behave properly"
  138.  
  139. -
  140. return myip
  141.  
  142.  
  143.  
  144.  
  145. -
  146. -
  147. -
  148. -
  149. ###################### Shared message / connection items ###################
Add Comment
Please, Sign In to add comment