def handle_time_exceeded(ip_packet): time_exceed = ip_packet.icmp.data if not isinstance(time_exceed.data, dpkt.ip.IP): return te_ip_packet = time_exceed.data if not isinstance(te_ip_packet.data, dpkt.icmp.ICMP): return te_icmp_packet = te_ip_packet.data if not isinstance(te_icmp_packet.data, dpkt.icmp.ICMP.Echo): return te_icmp_echo = te_icmp_packet.data ttl = te_icmp_echo.id dst_ip = socket.inet_ntoa(te_ip_packet.dst) router_ip = socket.inet_ntoa(ip_packet.src) is_china_router = china_ip.is_china_ip(router_ip) if is_china_router and MAX_TTL_TO_GFW == ttl: LOGGER.info('treat ip as domestic as max ttl is still in china: %s' % dst_ip) add_domestic_ip(dst_ip) return elif not is_china_router and MIN_TTL_TO_GFW == ttl: LOGGER.info('treat ip as international as min ttl is not in china: %s' % dst_ip) add_international_ip(dst_ip, MAX_TTL_TO_GFW) return else: pending_connection.record_router(dst_ip, ttl, is_china_router) ttl_to_gfw = pending_connection.get_ttl_to_gfw(dst_ip) if ttl_to_gfw: LOGGER.info('found ttl to gfw: %s %s' % (dst_ip, ttl_to_gfw)) add_international_ip(dst_ip, ttl_to_gfw)
def handle_time_exceeded(ip_packet): time_exceed = ip_packet.icmp.data if not isinstance(time_exceed.data, dpkt.ip.IP): return te_ip_packet = time_exceed.data if not isinstance(te_ip_packet.data, dpkt.icmp.ICMP): return te_icmp_packet = te_ip_packet.data if not isinstance(te_icmp_packet.data, dpkt.icmp.ICMP.Echo): return te_icmp_echo = te_icmp_packet.data ttl = te_icmp_echo.id dst_ip = socket.inet_ntoa(te_ip_packet.dst) router_ip = socket.inet_ntoa(ip_packet.src) is_china_router = china_ip.is_china_ip(router_ip) if is_china_router and MAX_TTL_TO_GFW == ttl: LOGGER.info( 'treat ip as domestic as max ttl is still in china: %s, %s' % (dst_ip, pending_connection.get_detected_routers(dst_ip))) add_domestic_ip(dst_ip) return else: pending_connection.record_router(dst_ip, ttl, is_china_router) ttl_to_gfw = pending_connection.get_ttl_to_gfw(dst_ip) if ttl_to_gfw: LOGGER.info('found ttl to gfw: %s %s' % (dst_ip, ttl_to_gfw - SAFETY_DELTA)) add_international_ip(dst_ip, ttl_to_gfw - SAFETY_DELTA)
def handle_time_exceeded(ip_packet): global MAX_TTL_TO_GFW global MIN_TTL_TO_GFW global RANGE_OF_TTL_TO_GFW time_exceed = ip_packet.icmp.data if not isinstance(time_exceed.data, dpkt.ip.IP): return te_ip_packet = time_exceed.data if not isinstance(te_ip_packet.data, dpkt.icmp.ICMP): return te_icmp_packet = te_ip_packet.data if not isinstance(te_icmp_packet.data, dpkt.icmp.ICMP.Echo): return te_icmp_echo = te_icmp_packet.data ttl = te_icmp_echo.id dst_ip = socket.inet_ntoa(te_ip_packet.dst) router_ip = socket.inet_ntoa(ip_packet.src) is_china_router = china_ip.is_china_ip(router_ip) if is_china_router and MAX_TTL_TO_GFW == ttl: LOGGER.info('treat ip as domestic as max ttl is still in china: %s, %s' % (dst_ip, pending_connection.get_detected_routers(dst_ip))) add_domestic_ip(dst_ip) return else: pending_connection.record_router(dst_ip, ttl, is_china_router) ttl_to_gfw = pending_connection.get_ttl_to_gfw(dst_ip) if ttl_to_gfw: LOGGER.info('found ttl to gfw: %s %s' % (dst_ip, ttl_to_gfw - SAFETY_DELTA)) if ttl_to_gfw == MAX_TTL_TO_GFW: MIN_TTL_TO_GFW += 2 MAX_TTL_TO_GFW += 2 LOGGER.info('slide ttl range to [%s ~ %s]' % (MIN_TTL_TO_GFW, MAX_TTL_TO_GFW)) RANGE_OF_TTL_TO_GFW = range(MIN_TTL_TO_GFW, MAX_TTL_TO_GFW + 1) add_international_ip(dst_ip, ttl_to_gfw - SAFETY_DELTA)
def handle_syn_ack(syn_ack): uncertain_ip = socket.inet_ntoa(syn_ack.src) full_proxy_service.add_to_white_list(uncertain_ip) if uncertain_ip in pending_syn: del pending_syn[uncertain_ip] expected_ttl = syn_ack_ttl.get((uncertain_ip, syn_ack.tcp.sport)) or 0 if expected_ttl and abs(syn_ack.ttl - expected_ttl) > 2: log_jamming_event(uncertain_ip, 'tcp syn ack spoofing') LOGGER.error( 'received spoofed SYN ACK: expected ttl is %s, actually is %s, the packet %s' % (expected_ttl, syn_ack.ttl, format_ip_packet(syn_ack))) syn_ack_ttl[( uncertain_ip, syn_ack.tcp.sport )] = syn_ack.ttl # later one should be the correct one as GFW is closer to us if uncertain_ip in international_zone: inject_poison_ack_to_fill_gfw_buffer_with_garbage( syn_ack, international_zone[uncertain_ip]) return True elif uncertain_ip in domestic_zone: return True elif pending_connection.is_ip_pending(uncertain_ip): pending_connection.record_syn_ack(syn_ack) timeouted = pending_connection.is_ip_timeouted(uncertain_ip) if timeouted: international_ip = uncertain_ip LOGGER.info( 'treat ip as international due to timeout: %s, %s' % (international_ip, pending_connection.get_detected_routers(international_ip))) ttl_to_gfw = pending_connection.get_ttl_to_gfw( international_ip, exact_match_only=False) add_international_ip(international_ip, (ttl_to_gfw or DEFAULT_TTL_TO_GFW) - SAFETY_DELTA) return False elif china_ip.is_china_ip(uncertain_ip): domestic_ip = uncertain_ip LOGGER.info('found domestic ip: %s' % domestic_ip) domestic_zone.add(domestic_ip) return True else: pending_connection.record_syn_ack(syn_ack) inject_ping_requests_to_find_right_ttl(uncertain_ip) return False
def handle_syn_ack(syn_ack): uncertain_ip = socket.inet_ntoa(syn_ack.src) full_proxy_service.add_to_white_list(uncertain_ip) if uncertain_ip in pending_syn: del pending_syn[uncertain_ip] expected_ttl = syn_ack_ttl.get((uncertain_ip, syn_ack.tcp.sport)) or 0 if expected_ttl and abs(syn_ack.ttl - expected_ttl) > 2: log_jamming_event(uncertain_ip, 'tcp syn ack spoofing') LOGGER.error( 'received spoofed SYN ACK: expected ttl is %s, actually is %s, the packet %s' % (expected_ttl, syn_ack.ttl, format_ip_packet(syn_ack))) syn_ack_ttl[ (uncertain_ip, syn_ack.tcp.sport)] = syn_ack.ttl # later one should be the correct one as GFW is closer to us if uncertain_ip in international_zone: inject_poison_ack_to_fill_gfw_buffer_with_garbage(syn_ack, international_zone[uncertain_ip]) return True elif uncertain_ip in domestic_zone: return True elif pending_connection.is_ip_pending(uncertain_ip): pending_connection.record_syn_ack(syn_ack) timeouted = pending_connection.is_ip_timeouted(uncertain_ip) if timeouted: international_ip = uncertain_ip ttl_to_gfw = pending_connection.get_ttl_to_gfw(international_ip, exact_match_only=False) LOGGER.info('treat ip as international due to timeout: %s, %s, %s' % (international_ip, ttl_to_gfw, pending_connection.get_detected_routers(international_ip))) add_international_ip(international_ip, (ttl_to_gfw or DEFAULT_TTL_TO_GFW) - SAFETY_DELTA) return False elif china_ip.is_china_ip(uncertain_ip): domestic_ip = uncertain_ip LOGGER.info('found domestic ip: %s' % domestic_ip) domestic_zone.add(domestic_ip) return True else: pending_connection.record_syn_ack(syn_ack) inject_ping_requests_to_find_right_ttl(uncertain_ip) return False