Last active
February 1, 2026 15:55
-
-
Save proudlygeek/07cddfb2a961ef70b779d320c6f770f5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Callbell LATAM Latency Test | |
| # Usage: curl -sL https://gist.githubusercontent.com/YOUR_USER/YOUR_GIST_ID/raw/callbell-latency-test.sh | bash | |
| echo "========================================" | |
| echo " Callbell LATAM Latency Test" | |
| echo "========================================" | |
| echo "" | |
| # Get public IP and location | |
| echo "π Your Connection Info:" | |
| echo "----------------------------------------" | |
| IP_INFO=$(curl -s https://ipinfo.io 2>/dev/null) | |
| if [ $? -eq 0 ]; then | |
| IP=$(echo "$IP_INFO" | grep -o '"ip": "[^"]*' | cut -d'"' -f4) | |
| CITY=$(echo "$IP_INFO" | grep -o '"city": "[^"]*' | cut -d'"' -f4) | |
| REGION=$(echo "$IP_INFO" | grep -o '"region": "[^"]*' | cut -d'"' -f4) | |
| COUNTRY=$(echo "$IP_INFO" | grep -o '"country": "[^"]*' | cut -d'"' -f4) | |
| ORG=$(echo "$IP_INFO" | grep -o '"org": "[^"]*' | cut -d'"' -f4) | |
| echo "IP: $IP" | |
| echo "Location: $CITY, $REGION, $COUNTRY" | |
| echo "ISP: $ORG" | |
| else | |
| echo "Could not determine IP info" | |
| fi | |
| echo "" | |
| # Test Cloudflare routing | |
| echo "π Cloudflare Routing (dash.callbell.eu):" | |
| echo "----------------------------------------" | |
| CF_TRACE=$(curl -s https://dash.callbell.eu/cdn-cgi/trace 2>/dev/null) | |
| if [ $? -eq 0 ]; then | |
| CF_COLO=$(echo "$CF_TRACE" | grep "^colo=" | cut -d'=' -f2) | |
| CF_LOC=$(echo "$CF_TRACE" | grep "^loc=" | cut -d'=' -f2) | |
| echo "Your location: $CF_LOC" | |
| echo "Cloudflare PoP: $CF_COLO" | |
| if [ "$CF_LOC" = "AR" ] && [ "$CF_COLO" != "EZE" ]; then | |
| echo "β οΈ WARNING: You should be routed to EZE (Buenos Aires), not $CF_COLO" | |
| ROUTING_ISSUE=1 | |
| elif [ "$CF_LOC" = "PE" ] && [ "$CF_COLO" != "LIM" ]; then | |
| echo "β οΈ WARNING: You should be routed to LIM (Lima), not $CF_COLO" | |
| ROUTING_ISSUE=1 | |
| elif [ "$CF_LOC" = "CO" ] && [ "$CF_COLO" != "BOG" ] && [ "$CF_COLO" != "MDE" ]; then | |
| echo "β οΈ WARNING: You should be routed to BOG/MDE (Colombia), not $CF_COLO" | |
| ROUTING_ISSUE=1 | |
| elif [ "$CF_LOC" = "CL" ] && [ "$CF_COLO" != "SCL" ]; then | |
| echo "β οΈ WARNING: You should be routed to SCL (Santiago), not $CF_COLO" | |
| ROUTING_ISSUE=1 | |
| elif [ "$CF_LOC" = "BR" ] && [ "$CF_COLO" != "GRU" ] && [ "$CF_COLO" != "GIG" ]; then | |
| echo "β οΈ WARNING: You should be routed to GRU/GIG (Brazil), not $CF_COLO" | |
| ROUTING_ISSUE=1 | |
| else | |
| echo "β Routing appears correct" | |
| ROUTING_ISSUE=0 | |
| fi | |
| else | |
| echo "Could not reach Cloudflare trace endpoint" | |
| fi | |
| echo "" | |
| # Test CloudFront routing | |
| echo "βοΈ CloudFront Routing (dash-sa.callbell.eu):" | |
| echo "----------------------------------------" | |
| CF_POP=$(curl -sI https://dash-sa.callbell.eu/health 2>/dev/null | grep -i "x-amz-cf-pop" | cut -d' ' -f2 | tr -d '\r') | |
| if [ -n "$CF_POP" ]; then | |
| echo "CloudFront PoP: $CF_POP" | |
| if [[ "$CF_POP" == EZE* ]]; then | |
| echo "β Hitting Buenos Aires edge" | |
| elif [[ "$CF_POP" == GRU* ]]; then | |
| echo "β Hitting SΓ£o Paulo edge" | |
| elif [[ "$CF_POP" == LIM* ]]; then | |
| echo "β Hitting Lima edge" | |
| elif [[ "$CF_POP" == BOG* ]]; then | |
| echo "β Hitting BogotΓ‘ edge" | |
| elif [[ "$CF_POP" == SCL* ]]; then | |
| echo "β Hitting Santiago edge" | |
| else | |
| echo "βΉοΈ Hitting $CF_POP edge" | |
| fi | |
| else | |
| echo "Could not determine CloudFront PoP" | |
| fi | |
| echo "" | |
| # Latency tests | |
| echo "β±οΈ Latency Tests (5 requests each):" | |
| echo "----------------------------------------" | |
| echo "" | |
| echo "dash.callbell.eu (Cloudflare):" | |
| CF_TIMES="" | |
| for i in 1 2 3 4 5; do | |
| TTFB=$(curl -w "%{time_starttransfer}" -o /dev/null -s https://dash.callbell.eu/health) | |
| TTFB_MS=$(echo "$TTFB * 1000" | bc 2>/dev/null || echo "$TTFB * 1000" | awk '{printf "%.0f", $1 * 1000}') | |
| echo " Request $i: ${TTFB_MS}ms" | |
| CF_TIMES="$CF_TIMES $TTFB" | |
| sleep 0.5 | |
| done | |
| echo "" | |
| echo "dash-sa.callbell.eu (CloudFront):" | |
| CFR_TIMES="" | |
| for i in 1 2 3 4 5; do | |
| TTFB=$(curl -w "%{time_starttransfer}" -o /dev/null -s https://dash-sa.callbell.eu/health) | |
| TTFB_MS=$(echo "$TTFB * 1000" | bc 2>/dev/null || echo "$TTFB * 1000" | awk '{printf "%.0f", $1 * 1000}') | |
| echo " Request $i: ${TTFB_MS}ms" | |
| CFR_TIMES="$CFR_TIMES $TTFB" | |
| sleep 0.5 | |
| done | |
| echo "" | |
| # Detailed timing for last request | |
| echo "π Detailed Timing Breakdown:" | |
| echo "----------------------------------------" | |
| echo "" | |
| echo "dash.callbell.eu (Cloudflare):" | |
| curl -w " DNS: %{time_namelookup}s\n Connect: %{time_connect}s\n TLS: %{time_appconnect}s\n TTFB: %{time_starttransfer}s\n Total: %{time_total}s\n" -o /dev/null -s https://dash.callbell.eu/health | |
| echo "" | |
| echo "dash-sa.callbell.eu (CloudFront):" | |
| curl -w " DNS: %{time_namelookup}s\n Connect: %{time_connect}s\n TLS: %{time_appconnect}s\n TTFB: %{time_starttransfer}s\n Total: %{time_total}s\n" -o /dev/null -s https://dash-sa.callbell.eu/health | |
| echo "" | |
| # MTR / Traceroute Network Path Analysis | |
| echo "π Network Path Analysis:" | |
| echo "----------------------------------------" | |
| # Check if MTR is available | |
| MTR_CMD="" | |
| if command -v mtr &> /dev/null; then | |
| MTR_CMD="mtr" | |
| elif [ -x "/usr/local/sbin/mtr" ]; then | |
| MTR_CMD="/usr/local/sbin/mtr" | |
| elif [ -x "/opt/homebrew/sbin/mtr" ]; then | |
| MTR_CMD="/opt/homebrew/sbin/mtr" | |
| fi | |
| if [ -n "$MTR_CMD" ]; then | |
| # MTR is available | |
| echo "Using MTR for detailed path analysis." | |
| echo "" | |
| # Check if we have sudo access or are root | |
| CAN_RUN_MTR=0 | |
| if [ "$EUID" -eq 0 ]; then | |
| CAN_RUN_MTR=1 | |
| SUDO_PREFIX="" | |
| elif sudo -n true 2>/dev/null; then | |
| CAN_RUN_MTR=1 | |
| SUDO_PREFIX="sudo" | |
| else | |
| echo "MTR requires administrator privileges for raw socket access." | |
| echo "" | |
| read -p "Enter sudo password to run MTR? [y/N]: " -n 1 -r | |
| echo "" | |
| if [[ $REPLY =~ ^[Yy]$ ]]; then | |
| if sudo -v 2>/dev/null; then | |
| CAN_RUN_MTR=1 | |
| SUDO_PREFIX="sudo" | |
| else | |
| echo "β οΈ Could not obtain sudo access. Falling back to traceroute." | |
| CAN_RUN_MTR=0 | |
| fi | |
| else | |
| echo "βΉοΈ Skipping MTR, falling back to traceroute." | |
| CAN_RUN_MTR=0 | |
| fi | |
| fi | |
| if [ "$CAN_RUN_MTR" -eq 1 ]; then | |
| MTR_CYCLES=50 | |
| echo "Running MTR with $MTR_CYCLES packets (this takes ~1 minute)..." | |
| echo "" | |
| echo "β dash.callbell.eu (Cloudflare):" | |
| echo "" | |
| $SUDO_PREFIX $MTR_CMD -rwc $MTR_CYCLES dash.callbell.eu 2>/dev/null | |
| echo "" | |
| echo "β dash-sa.callbell.eu (CloudFront):" | |
| echo "" | |
| $SUDO_PREFIX $MTR_CMD -rwc $MTR_CYCLES dash-sa.callbell.eu 2>/dev/null | |
| echo "" | |
| else | |
| # Fall back to traceroute | |
| MTR_CMD="" | |
| fi | |
| fi | |
| # Fallback to traceroute if MTR not available or couldn't run | |
| if [ -z "$MTR_CMD" ] || [ "${CAN_RUN_MTR:-1}" -eq 0 ]; then | |
| echo "βΉοΈ Using built-in traceroute for path analysis." | |
| if [[ "$OSTYPE" == "darwin"* ]]; then | |
| echo " (For better diagnostics with packet loss stats: brew install mtr)" | |
| fi | |
| echo "" | |
| echo "β dash.callbell.eu (Cloudflare):" | |
| echo "" | |
| if [[ "$OSTYPE" == "darwin"* ]]; then | |
| # macOS traceroute | |
| traceroute -n -q 3 -w 2 dash.callbell.eu 2>/dev/null || traceroute dash.callbell.eu 2>/dev/null | |
| else | |
| # Linux traceroute (might need -I for ICMP, or use tracepath as fallback) | |
| if command -v traceroute &> /dev/null; then | |
| traceroute -n -q 3 -w 2 dash.callbell.eu 2>/dev/null || traceroute dash.callbell.eu 2>/dev/null | |
| elif command -v tracepath &> /dev/null; then | |
| tracepath dash.callbell.eu 2>/dev/null | |
| else | |
| echo " traceroute/tracepath not available" | |
| fi | |
| fi | |
| echo "" | |
| echo "β dash-sa.callbell.eu (CloudFront):" | |
| echo "" | |
| if [[ "$OSTYPE" == "darwin"* ]]; then | |
| traceroute -n -q 3 -w 2 dash-sa.callbell.eu 2>/dev/null || traceroute dash-sa.callbell.eu 2>/dev/null | |
| else | |
| if command -v traceroute &> /dev/null; then | |
| traceroute -n -q 3 -w 2 dash-sa.callbell.eu 2>/dev/null || traceroute dash-sa.callbell.eu 2>/dev/null | |
| elif command -v tracepath &> /dev/null; then | |
| tracepath dash-sa.callbell.eu 2>/dev/null | |
| else | |
| echo " traceroute/tracepath not available" | |
| fi | |
| fi | |
| echo "" | |
| # On macOS 12+, also run networkQuality if available | |
| if command -v networkQuality &> /dev/null; then | |
| echo "β Network Quality (macOS built-in):" | |
| echo "" | |
| networkQuality -s 2>/dev/null | |
| echo "" | |
| fi | |
| fi | |
| # Full Cloudflare trace for debugging | |
| echo "π Full Cloudflare Trace (for support tickets):" | |
| echo "----------------------------------------" | |
| curl -s https://dash.callbell.eu/cdn-cgi/trace 2>/dev/null | |
| echo "" | |
| # Summary and recommendation | |
| if [ "${ROUTING_ISSUE:-0}" -eq 1 ]; then | |
| echo "========================================" | |
| echo "β οΈ ROUTING ISSUE DETECTED" | |
| echo "========================================" | |
| echo "" | |
| echo "Your traffic is being routed to a distant Cloudflare PoP." | |
| echo "This may cause increased latency. Please share these results" | |
| echo "with Callbell support: soporte@callbell.eu" | |
| echo "" | |
| fi | |
| echo "========================================" | |
| echo " Test completed: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" | |
| echo "========================================" | |
| echo "" | |
| echo "π§ Please copy all output above and send to: soporte@callbell.eu" | |
| echo "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment