Traceroute - иногда не работают сокеты - PullRequest
0 голосов
/ 06 декабря 2018

Я пишу traceroute на Python3 в качестве упражнения.Он работает довольно хорошо, но время от времени трассировка не сможет получить ответ от определенного прыжка и будет продолжать увеличивать TTL, даже не получив ответа.Обычная программа трассировки linux не страдает от этой проблемы, поэтому она должна быть в моем коде.

Я пробовал разные варианты, но все они страдают от одной и той же проблемы.Я буду запускать трассировку на 8.8.8.8 и 4 из 5 раз, она отлично работает.

Я пробовал создавать сокеты, используя менеджер контекста (с сокетом как ...), а также вручную.

import os
import random
import socket
import sys
import time

class Traceroute:
def __init__(self, dest, maxhops=30, port=random.randrange(33434,33534), host=''):
    self.dest = dest
    self.maxhops = maxhops
    self.port = port
    self.host = host
    self.hops = []

# Function for creating new sockets
def get_socket(self,type,proto=0):
    s = socket.socket(
        family=socket.AF_INET,
        type=type,
        proto=proto
    )
    s.bind((self.host,self.port))
    return s

# Do the trace and store hop information for later use
def get_path(self):
    try:
        self.dest_ip = socket.gethostbyname(self.dest)
        self.dest_name = socket.gethostbyaddr(self.dest)[0]
    except socket.gaierror as e:
        print(f'Error: {self.dest} - {e}')

    address = ['']
    ttl = 1
    while ttl < self.maxhops +1 and address[0] != self.dest_ip:
            receiver_socket = self.get_socket(socket.SOCK_RAW,socket.getprotobyname('icmp'))
            receiver_socket.settimeout(2)
            sender_socket = self.get_socket(socket.SOCK_DGRAM,socket.getprotobyname('udp'))
            sender_socket.setsockopt(socket.SOL_IP,socket.IP_TTL,ttl)
            sender_socket.sendto(b'',(self.dest_ip,self.port))
            tries = 3
            while tries > 0:
                starttime = time.time()
                try:
                    data, address = receiver_socket.recvfrom(1024)
                    latency = [round((time.time()-starttime)*1000,2)]
                    try:
                        hostname = socket.gethostbyaddr(address[0])[0]
                    except socket.herror as e:
                        hostname = address[0]
                    self.hops.append({
                        'address':address[0],
                        'hostname':hostname,
                        'latency': latency
                    })
                    tries = 0
                except socket.error:
                    tries -= 1
                    if tries == 0:
                        self.hops.append({
                            'address':None,
                            'hostname':ttl,
                            'latency':None
                            })
                finally:
                    receiver_socket.close()
                    sender_socket.close()
            ttl += 1
            os.system('clear')
            self.draw()

def draw(self):
    name = f'{self.dest_ip} - {self.dest_name}' if self.dest_name != self.dest_ip else self.dest_ip
    print(f'Traceroute to {name}')
    # Print the full hop list, for debugging
    for hop in self.hops:
        print(hop)
    # Print the hops in a readable fashion
    for hop in self.hops:
        if hop['address'] is None:
            print(f"{self.hops.index(hop)+1} - {'*':<50} - {'*':<50} - {'*':<50}")
        else:
            latencylen = len(hop['latency'])
            latencyavg = str(round(sum(hop['latency'])/latencylen,2)) + 'ms'
            name = f'{hop["address"]} - {hop["hostname"]}' if hop['address'] != hop['hostname'] else hop['address']
            print(f'{self.hops.index(hop)+1} - {name:<50} - {latencyavg:<50} - LEN:{latencylen:<50}')

def main():
if len(sys.argv) < 2:
    print('Please enter a destination')
else:
    trace = Traceroute(sys.argv[1])
    trace.get_path()

if __name__ == '__main__':
main()

Вот вывод, когда он полностью содержит ошибки:

self.hops - список словарей.

Материал в {скобках} - это словарь прыжковсам.Я добавил это для отладки.Обратите внимание, что прыжки 2 и 3 идентичны.Таким образом, след как-то столкнулся с этим прыжком дважды.Число в начале строки является индексом списка, который также представляет TTL.Я обычно достигаю 8.8.8.8 к 9-му прыжку, но в этом случае он просто продолжает идти, увеличивая TTL, пока не достигнет максимума.

Traceroute to 8.8.8.8 - google-public-dns-a.google.com
{'address': '192.168.1.1', 'hostname': '_gateway', 'latency': [8.21]}
{'address': '104.195.128.122', 'hostname': '104-195-128-122.cpe.teksavvy.com', 'latency': [1572.38]}
{'address': '104.195.128.122', 'hostname': '104-195-128-122.cpe.teksavvy.com', 'latency': [15.97]}
{'address': '104.195.129.9', 'hostname': '104-195-129-9.cpe.teksavvy.com', 'latency': [27.22]}
{'address': '206.248.155.92', 'hostname': 'ae10-0-bdr01-tor2.teksavvy.com', 'latency': [20.05]}
{'address': '206.248.155.10', 'hostname': 'ae12-0-bdr01-tor.teksavvy.com', 'latency': [27.2]}
{'address': None, 'hostname': 7, 'latency': None}
{'address': None, 'hostname': 8, 'latency': None}
{'address': None, 'hostname': 9, 'latency': None}
{'address': None, 'hostname': 10, 'latency': None}
{'address': None, 'hostname': 11, 'latency': None}
{'address': None, 'hostname': 12, 'latency': None}
{'address': None, 'hostname': 13, 'latency': None}
{'address': None, 'hostname': 14, 'latency': None}
{'address': None, 'hostname': 15, 'latency': None}
1 - 192.168.1.1 - _gateway                             - 8.21ms                                             - LEN:1                                                 
2 - 104.195.128.122 - 104-195-128-122.cpe.teksavvy.com - 1572.38ms                                          - LEN:1                                                 
3 - 104.195.128.122 - 104-195-128-122.cpe.teksavvy.com - 15.97ms                                            - LEN:1                                                 
4 - 104.195.129.9 - 104-195-129-9.cpe.teksavvy.com     - 27.22ms                                            - LEN:1                                                 
5 - 206.248.155.92 - ae10-0-bdr01-tor2.teksavvy.com    - 20.05ms                                            - LEN:1                                                 
6 - 206.248.155.10 - ae12-0-bdr01-tor.teksavvy.com     - 27.2ms                                             - LEN:1                                                 
7 - *                                                  - *                                                  - *                                                 
8 - *                                                  - *                                                  - *                                                 
9 - *                                                  - *                                                  - *                                                 
10 - *                                                  - *                                                  - *                                                 
11 - *                                                  - *                                                  - *                                                 
12 - *                                                  - *                                                  - *                                                 
13 - *                                                  - *                                                  - *                                                 
14 - *                                                  - *                                                  - *                                                 
15 - *                                                  - *                                                  - *            

Спасибо,

...