Merge pull request #171 from jhass/mapped_ip

Handle IPv4-mapped IPv6 addresses
This commit is contained in:
ThomasWaldmann 2014-09-29 11:18:36 +02:00
commit b758ca3e89
4 changed files with 27 additions and 7 deletions

View File

@ -22,6 +22,7 @@ from ..utils import log, ddns_client
from ..main.models import Host
from ..main.dnstools import (FQDN, update, delete, check_ip, put_ip_into_session,
SameIpError, DnsUpdateError, NameServerNotAvailable)
from ..main.iptools import normalize_ip
def Response(content):
@ -44,7 +45,7 @@ def myip_view(request, logger=None):
"""
# Note: keeping this as a function-based view, as it is frequently used -
# maybe it is slightly more efficient than class-based.
ipaddr = request.META['REMOTE_ADDR']
ipaddr = normalize_ip(request.META['REMOTE_ADDR'])
logger.debug("detected remote ip address: %s" % ipaddr)
return Response(ipaddr)
@ -64,7 +65,7 @@ class DetectIpView(View):
# so the session cookie is not received here - thus we access it via
# the sessionid:
s = SessionStore(session_key=sessionid)
ipaddr = request.META['REMOTE_ADDR']
ipaddr = normalize_ip(request.META['REMOTE_ADDR'])
# as this is NOT the session automatically established and
# also saved by the framework, we need to use save=True here
put_ip_into_session(s, ipaddr, save=True)
@ -225,7 +226,7 @@ class NicUpdateView(View):
return Response('badagent')
ipaddr = request.GET.get('myip')
if not ipaddr: # None or ''
ipaddr = request.META.get('REMOTE_ADDR')
ipaddr = normalize_ip(request.META.get('REMOTE_ADDR'))
secure = request.is_secure()
if delete:
return _delete(host, ipaddr, secure, logger=logger)
@ -283,7 +284,7 @@ class AuthorizedNicUpdateView(View):
# and logged-in usage - thus misbehaved user agents are no problem.
ipaddr = request.GET.get('myip')
if not ipaddr: # None or empty string
ipaddr = request.META.get('REMOTE_ADDR')
ipaddr = normalize_ip(request.META.get('REMOTE_ADDR'))
secure = request.is_secure()
if delete:
return _delete(host, ipaddr, secure, logger=logger)

View File

@ -10,6 +10,7 @@ logger = logging.getLogger(__name__)
import time
from .main.dnstools import put_ip_into_session
from .main.iptools import normalize_ip
from django.conf import settings
@ -36,7 +37,7 @@ def update_ips(request):
s = request.session
t_now = int(time.time())
# update and keep fresh using info from the request we have anyway:
ipaddr = request.META['REMOTE_ADDR']
ipaddr = normalize_ip(request.META['REMOTE_ADDR'])
put_ip_into_session(s, ipaddr, max_age=MAX_IP_AGE / 2)
# remove stale data to not show outdated IPs (e.g. after losing IPv6 connectivity):
for key in ['ipv4', 'ipv6', ]:

17
nsupdate/main/iptools.py Normal file
View File

@ -0,0 +1,17 @@
"""
Misc. IP tools: normalize, handle mapped addresses
"""
from netaddr import IPAddress
def normalize_ip(ipaddr):
ipaddr = normalize_mapped_address(ipaddr)
return ipaddr
def normalize_mapped_address(ipaddr):
ipaddr = IPAddress(ipaddr)
if ipaddr.is_ipv4_compat() or ipaddr.is_ipv4_mapped():
ipaddr = ipaddr.ipv4()
return str(ipaddr)

View File

@ -19,6 +19,7 @@ from django.core.exceptions import PermissionDenied
from django.utils.timezone import now
from . import dnstools
from .iptools import normalize_ip
from .forms import (CreateHostForm, EditHostForm, CreateRelatedHostForm, EditRelatedHostForm,
CreateDomainForm, EditDomainForm, CreateUpdaterHostConfigForm, EditUpdaterHostConfigForm)
@ -210,7 +211,7 @@ class AddHostView(CreateView):
def form_valid(self, form):
self.object = form.save(commit=False)
try:
dnstools.add(self.object.get_fqdn(), self.request.META['REMOTE_ADDR'])
dnstools.add(self.object.get_fqdn(), normalize_ip(self.request.META['REMOTE_ADDR']))
except dnstools.Timeout:
success, level, msg = False, messages.ERROR, 'Timeout - communicating to name server failed.'
except dnstools.NameServerNotAvailable:
@ -265,7 +266,7 @@ class HostView(UpdateView):
def get_context_data(self, *args, **kwargs):
context = super(HostView, self).get_context_data(*args, **kwargs)
context['nav_overview'] = True
context['remote_addr'] = self.request.META['REMOTE_ADDR']
context['remote_addr'] = normalize_ip(self.request.META['REMOTE_ADDR'])
return context