# Copyright 2009 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Specific connections to DNS server providers."""

__author__ = 'tstromberg@google.com (Thomas Stromberg)'

import sys

if __name__ == '__main__':
  sys.path.append('..')
  import nb_third_party

import addr_util
import nameserver
import sys_nameservers

OPENDNS_IP = '208.67.220.220'
MY_RESOLVER_IP = '188.165.43.98'
GOOGLE_IP = '8.8.8.8'


class OpenDNS(nameserver.NameServer):
  def __init__(self, ip=OPENDNS_IP):
    super(OpenDNS, self).__init__(ip=ip)

  def InterceptionStateWithDuration(self):
    return self.GetOpenDnsInterceptionStateWithDuration()

class MyResolverInfo(nameserver.NameServer):
  def __init__(self, ip=MY_RESOLVER_IP):
    super(MyResolverInfo, self).__init__(ip=ip)

  def ClientIp(self):
    return self.GetMyResolverIpWithDuration()[0]


class GooglePublicDNS(nameserver.NameServer):
  def __init__(self, ip=GOOGLE_IP):
    super(GooglePublicDNS, self).__init__(ip=ip)

class SystemResolver(nameserver.NameServer):
  def __init__(self, ip=None):
    if not ip:
      ip = self._GetPrimaryIP()
    super(SystemResolver, self).__init__(ip=ip)

  def _GetPrimaryIP(self):
    internal = sys_nameservers.GetCurrentNameServers()
    if not internal:
      internal = sys_nameservers.GetAssignedNameServers()
    if not internal:
      print 'Odd - no built-in nameservers found.'
      return None
    else:
      return internal[0]
    return None

  def GetNetworkDataForIp(self, ip):
    class_c = addr_util.GetNetworkForIp(ip, reverse=True)
    host = '%s.origin.asn.cymru.com.' % class_c
    answer = self.GetTxtRecordWithDuration(host)
    return answer[0].split(' | ')

  def GetAsnForIp(self, ip):
    return self.GetNetworkDataForIp(ip)[0]

  def GetMyAsn(self):
    ip = MyResolverInfo().ClientIp()
    return self.GetAsnForIp(ip)


if __name__ == '__main__':
  print OpenDNS().InterceptionStateWithDuration()
  print MyResolverInfo().ClientIp()
  print SystemResolver().GetAsnForIp(MyResolverInfo().ClientIp())

@@ -701,16 +701,26 @@
 berg)'%0A%0A
+import re%0A
 import s
@@ -858,16 +858,34 @@
 ervers%0A%0A
+import httplib2%0A%0A%0A
 OPENDNS_
@@ -910,63 +910,198 @@
 20'%0A
-MY_RESOLVER_IP = '188.165.43.98'%0AGOOGLE_IP = '8.8.8.8'%0A
+# TODO(tstromberg): Stop hardcoding ns2.myresolver.info.%0AMY_RESOLVER_IP = '188.165.43.98'%0AGOOGLE_IP = '8.8.8.8'%0ADYNDNS_IP = 'http://checkip.dyndns.org/'%0AIFCONFIG_IP = 'http://ifconfig.me/ip'
 %0A%0Acl
@@ -1458,16 +1458,19 @@
 %0A%0A  def 
+Dns
 ClientIp
@@ -1526,16 +1526,787 @@
 on()%5B0%5D%0A
+    %0Aclass ExternalIpAtUrl(object):%0A  %0A  def FindIpAtUrl(self, url):%0A    h = httplib2.Http(timeout=10)%0A    _, content = h.request(url, 'GET')%0A    if content:%0A      ips = addr_util.ExtractIPsFromString(content)%0A      if ips:%0A        return ips%5B0%5D%0A%0Aclass IfConfigMe(ExternalIpAtUrl):%0A  %0A  def IfConfigIp(self, url=IFCONFIG_IP):%0A    return self.FindIpAtUrl(url)%0A%0Aclass DynDns(object):%0A  %0A  def CheckIp(self, url=DYNDNS_IP):%0A    return self.FindIpAtUrl(url)%0A%0Aclass AnyExternalIpHost(MyResolverInfo, IfConfigMe, DynDns):%0A  %0A  %22%22%22Try by DNS first, then use DynDNS to get the external IP.%22%22%22%0A%0A  %0A  def ClientIp(self):%0A    for method in (self.DnsClientIp, self.IfConfigIp, self.CheckIp):%0A      ip = method()%0A      if ip:%0A        print %22Found IP via %25s%22 %25 method%0A        return ip
 %0A%0Aclass 
@@ -3098,16 +3098,68 @@
 n(host)%0A
+    if answer and answer%5B0%5D and '%7C' in answer%5B0%5D:%0A  
     retu

Add some fallback methods (ifconfig.me, dyndns) to determine external IP when myresolver is down