Автор Тема: "Редуциране" на ping response time-а - търся съвет  (Прочетена 6598 пъти)

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Сега като се замисля има начин, ще си поиграя вкъщи и ще пиша. В крайна сметка, повечето ping имплементации слагат timestamp в payload-а на пакета явно...ще видя може ли да се направи нещо по въпроса...
Активен

"Knowledge is power" - France is Bacon

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
Аз имах предвид повишаване на приоритета, ако такова нещо е възможно.
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

b2l

  • Напреднали
  • *****
  • Публикации: 4786
  • Distribution: MCC Interim
  • Window Manager: - // - // -
  • ...sometimes I feel like screaming... || RTFM!
    • Профил
    • WWW
Аз имах предвид повишаване на приоритета, ако такова нещо е възможно.

Приоритет на какво?
Активен

"Човекът е въже, опънато между звяра и свръхчовека, въже над пропаст. Човекът е нещо, което трябва да бъде превъзмогнато." - Фр. Ницше

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Timestamp наистина има в ICMP ECHО пакетите, но не в хедъра, повечето ping имплементации го слагат в payload-а на пакета, който по спецификация трябва да се върне в същия вид. Това явно е вид оптимизация - за да не им се налага да пазят информация кой пакет кога е изпратен (при ping -f това би било доста брутално).

Също така може да се върне ICMP ECHO REPLY пакет с модифициран timestamp, не с подръчните средства, но може да се напише програмка, която го прави. Има обаче много въпросителни. Вкъщи имам разни заигравки с raw сокети от едно време, ще модифицирам една от тях за целта и ще пробвам. Склонен съм да вярвам, че няма начин да се направи reliable, но ще е интересна занимавка. След час-два ще пиша пак.
Активен

"Knowledge is power" - France is Bacon

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Тъй, готово. Експериментът....донякъде успешен, за справка:

Код:
ping www.gat3way.eu

Естествено не прави точно това което се иска, а е просто PoC експеримент. Ако на някой му се играе:

Код:
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>


#define PACKETSIZE 64
struct packet
{
        struct iphdr iphdr;
        struct icmphdr hdr;
        char msg[PACKETSIZE-sizeof(struct icmphdr)];
};

struct protoent *proto=NULL;

unsigned short checksum(void *b, int len)
{       unsigned short *buf = b;
        unsigned int sum=0;
        unsigned short result;

        for (sum = 0;len>1;len-=2) sum += *buf++;
        if (len == 1) sum += *(unsigned char*)buf;
        sum = (sum >> 16) + (sum & 0xFFFF);
        sum += (sum >> 16);
        result = ~sum;
        return result;
}


unsigned short reverse2 (unsigned short nValue)
{
   return (((nValue>> 8)) | (nValue << 8));
}


void fuckicmp(struct sockaddr_in *addr)
{       const int val=255;
        int i, sd, cnt=1;
        short cs;
        struct packet pckt;
        struct sockaddr_in r_addr;
        char icmppacket[64];
        int sum;

        sd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
        if (sd < 0)
        {
                perror("socket");
                return;
        }
        if (setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0)
                perror("Set TTL option");
        if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &val, sizeof(val)) < 0)
             perror("setsockopt() for IP_HDRINCL error");

        for (;;)
        {
                int len=sizeof(r_addr);
                if ( recvfrom(sd, &pckt, sizeof(pckt), sizeof(pckt), (struct sockaddr*)&r_addr, &len) > 0 )
                if (pckt.hdr.type==ICMP_ECHO)
                {
                    printf("Got icmp type=%d id=%d seq=%d\n",pckt.hdr.type,reverse2(pckt.hdr.un.echo.id),reverse2(pckt.hdr.un.echo.sequence));

                    pckt.hdr.type = ICMP_ECHOREPLY;
                    pckt.hdr.checksum = 0;
                    int src,dst;
                    src=pckt.iphdr.saddr;
                    dst=pckt.iphdr.daddr;
                    pckt.iphdr.daddr=src;
                    pckt.iphdr.saddr=dst;

                    //Uncomment to lie about pings, decrease response time by ~650ms
                    pckt.msg[6]+=10;

                    //Uncomment to make fun of users
                    //pckt.msg[3]+=20;

                    memcpy(icmppacket,&pckt.hdr,sizeof(struct icmphdr));
                    memcpy(&icmppacket[sizeof(struct icmphdr)],&pckt.msg,64-sizeof(struct icmphdr));
                    pckt.hdr.checksum=checksum(icmppacket,64);

                    if ( sendto(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)&r_addr, sizeof(r_addr)) <= 0 )
                        perror("sendto");
                }
        }
}

int main(int count, char *strings[])
{       struct hostent *hname;
        struct sockaddr_in addr;
        char *str="127.0.0.1";

        proto = getprotobyname("ICMP");
        hname = gethostbyname(str);
        bzero(&addr, sizeof(addr));
        addr.sin_family = hname->h_addrtype;
        addr.sin_port = 0;
        addr.sin_addr.s_addr = *(long*)hname->h_addr;
        addr.sin_addr.s_addr = INADDR_ANY;
        fuckicmp(&addr);

        return 0;
}


За да  тествате, първо забранявате echo response-ите от ядрото:

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

После компилирате и пускате горната програма като root.


Сега къде са проблемите и защо мисля, че подходът няма да доведе до решение на проблема:

1) Работи само при packet size=64, дефолтната в линукс. При други вероятно ще се счупи. Това лесно се оправя.
2) Правено е на базата на сорса на ping в линукс, където timespec структурата е първото нещо в payload-a и знаем точно къде да бутнем, за да променим резултата. Структурата между другото е архитектурно-зависима, така че ping от powerpc система примерно ще трябва да се handle-ва по друг начин. По-лошото е че windows ползва друг формат, не знам как и къде се пази timestamp-а, нямам сорса и единственият начин е да се снифи трафик и да се пробва.


Горните проблеми са разрешими, но най-големият проблем е че не можем лесно да "намаляме" response time-а освен ако часовниците на двете машини са синхронизирани, което обикновено не е случая. Тоест (както сигурно сте забелязали) можем да намаляме response time-a с милисекунди, но не можем да го вкараме в някакви разумни мярки и когато клиентът забележи, че timestamp-а е в бъдещето, се оплаква.

За целта трябва да се направи state таблица и промените да стават на база делтите между timestamp-овете на пристигналите icmp пакет-и, които могат да варират доста при бавна връзка. В идеалният случай може да се направи нещо което сработва след няколко получени пакети, но за първите пристигнали не можем да излъжим, няма начин освен ако не се сдобием с някакви свръхестествени способности.
« Последна редакция: Nov 01, 2011, 18:58 от gat3way »
Активен

"Knowledge is power" - France is Bacon

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
Аз имах предвид повишаване на приоритета, ако такова нещо е възможно.

Приоритет на какво?
На трафика - [ -Q tos ]
« Последна редакция: Nov 01, 2011, 21:22 от laskov »
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

abadon

  • Напреднали
  • *****
  • Публикации: 510
  • Distribution: Debian
  • Window Manager: KDE
    • Профил
    • WWW
@abadon
Не съм съгласен с "Всички ние знаем че тези ms не са мерило за това колко ти е бърза връзката."

И тези ms са мерило. Тук  http://delian.blogspot.com/2008/03/network-performance-tuning-windows.html човека го е обяснил.

"TCP протоколът е този, който се използва в над 90% от вашата комуникация по Интернет или в локалната мрежа. Той цели да осигури сигурен пренос на данните – тоест данните се изпращат и се потвърждават че са получени правилно (пресмята се контролната им сума и се сравнява с тази записана във всеки пакет). Ако не са получени правилно не се потвърждават. Изпращащата страна изчаква малко време и изпраща непотвърдените участъци пак. За да не се налага да се потвърждава всеки пакет, преди да бъде изпратен следващия (понеже това ще ограничи максималната скорост на сесия в посока до големината на пакета за RTT време (RTT е времето необходимо за отиване и връщане на пакет), понеже всеки пакет с данни трябва да бъде потвърден преди да се изпрати следващия) потвържденията се правят на сегменти, които се наричат Windows (няма общо с Microsoft). Всяка страна казва на отсрещната непрестанно какъв е нейния моментен прозорец, от максимум байтове, които могат да бъдат изпратени към нея без потвърждение. Смисъла на това е, че така приемащата страна може да има нещо като Flow Control механизъм – ако има малък по размер буфер, ще е сигурна, че изпращача няма да изпрати повече данни от размера на този буфер (ако ние сме му казали максимален Receive Window <= на размера на буфера). Ако пък приложението четящо данните се бави, намаляваме Receive Window-а, и така намаляваме количеството данни, които да се трупат в буфера, до на практика пълното им спиране. Като прост ефект от това следва и формулата за максимална скорост на предаване на данни чрез TCP протокол в посока – тя е един Receive Window за RTT време. Или ако RTT е в милисекунди, то скоростта е (Receive Window * 1000)/RTT байтове в секунда.

И сега да се върнем към Windows – при него по подразбиране Receive Window е 8KB/17KB (при Linux е 32KB или 64KB в зависимост от Kernel-а). Следователно ако между двете комуникиращи си машини ping-а дава средно закъснение от 100мс, максималната скорост на трансфер към Windows ще бъде 8KB*1000/100 за секунда, или 80KB/сек. За пример Linux ще постигне при същите параметри 320KB/сек, само поради разликата в конфигурацията..."

http://en.wikipedia.org/wiki/TCP_tuning

Интересна информация си ми дал. Само дето тези неща ги знам и съм ги чел много много отдавна, тъй като Делян ми приятел от 5-6 години. Около 2.5 години работех за него в бившата му фирма преди да се разпадне и т.н....

Точно днес с него дискутирах въпроса, каза че може да се напише iptables модул със стотина реда код който да дропи icmp echo request-ите, след което с libpcap след желаното време да се пращат icmp echo replay от името на хоста получател и така ping-а да се излъже. Като имал повече време след няколко седмици ще го разгледал въпроса, че му стана интересно.


@gat3way - Може да погледнеш идеята на Делян

Аз имах предвид повишаване на приоритета, ако такова нещо е възможно.

Приоритет на какво?
На трафика - [ -Q tos ]

Приоритизацията на трафика не помага в този случай. Тя се ползва за други неща, като примерно Quality of service или при правене на шейпъри.

Дори и с най-висок приоритет да пращаш icmp пакетите въобще няма да промени response time-а ако мрежата ти не е претоварена и всичко работи както трябва, както е в моя случай. Виж ако си си запълнил канала на max може би ще се свали с малко времето, но едва ли ще е повече от няколко ms. От опита ми с проектирането и работата с мрежите знам, че на ~100Km физическо разстояние отговаря 1ms забавяне.  Това е времето нужно на светлината по оптично влакно да измине разстоянието от изпращача до получателя. Затова единствения сигурен метод за драстично сваляне е да се измисли как светлината да се свижи по-бързо....
« Последна редакция: Nov 02, 2011, 01:16 от abadon »
Активен

Успешното Boot-ване на Windows завършва с рестарт!!!
You are registered as user #382190 with the Linux Counter
Всеки пост - отговор на въпрос

CTEHATA

  • Напреднали
  • *****
  • Публикации: 101
    • Профил
За техническата страна на нещата, предполагам че можеш да го решиш по много начини, като при по-добрите от тях, дори и клиентът да е с негов лаптоп за тестовете, пак ще го преметнеш. Най-мазно би било да модифицираш тялото на ICMP пакета. При код, който връща фалшив пакет след кратко забавяне, клиентът може да се усети ако тества бавен сървър

Има обаче един проблем. ВИНАГИ, когато излъжеш клиент рискуваш много.
Ако се окаже, че клиентът се интересува САМО от латентността (за някои приложения bandwith над някаква граница не е интересен), а ти го преметнеш, можеш да си навлечеш големи проблеми. Ако индиецът са го пратили да гледа пингове, защото ше ползват отдалечена база данни и някакво клиентско приложение, твоите трикове ще се окажат класическа измама. В държави като Германия, това може да има последици и за теб.

Най-добре ще е, ако просто намериш начин за зрелищна демонстрация на капацитета, който предлагаш ти. Ако се справиш добре, всеки клиент с поне малко мозък, ще те разбере. Така ще губиш само безмозъчните клиенти, но те са и тия, които правят най-много проблеми.

На твое място бих зарязал пинга, а бих наблегнал на демо с 10 HD камери, които предават едновременно или нещо подобно.
Активен

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
HDD ext3 recover, "Stellar Phoenix Linux" ??
Настройка на хардуер
help40 3 6363 Последна публикация Sep 20, 2012, 21:51
от Acho
При Ping: "Time to live exceeded"
Настройка на програми
Astor 17 5729 Последна публикация Aug 26, 2005, 09:55
от George Andonov
"paskal case" / "camel case"
Общ форум
Apache 3 7721 Последна публикация Aug 11, 2006, 10:01
от ivak
Проблем с "struct cdev" и "struct semaphore"
Общ форум
halturata 22 13080 Последна публикация Aug 14, 2007, 17:31
от tarator
Проблем с "reboot", "halt" и т.н.
Настройка на програми
turboshark 5 7469 Последна публикация Sep 22, 2007, 00:13
от turboshark