]> git.tdb.fi Git - netvis.git/commitdiff
Resolve IP addresses to hostnames
authorMikko Rasa <tdb@tdb.fi>
Thu, 7 Feb 2008 14:59:44 +0000 (14:59 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 7 Feb 2008 14:59:44 +0000 (14:59 +0000)
Cap the rate at which to generate packets from hosts
Reduce the number of GL calls in rendering packets
A lot of other changes

source/host.cpp
source/host.h
source/netvis.cpp
source/netvis.h
source/packet.cpp
source/packet.h
source/resolver.cpp [new file with mode: 0644]
source/resolver.h [new file with mode: 0644]
source/vector2.h

index be24f05360d05060455228e66b6492dbb2160397..e5eafc899fd98db7bd9d851fb208b237f72b1619 100644 (file)
@@ -1,3 +1,10 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
 #include <cmath>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -14,11 +21,48 @@ using namespace Msp;
 
 Host::Host(NetVis &nv, unsigned a):
        netvis(nv),
-       addr(a)
+       addr(a),
+       local(false),
+       active(true),
+       activity(0),
+       throttle(0)
 {
        in_addr ina;
        ina.s_addr=htonl(addr);
        name=inet_ntoa(ina);
+       short_name=name;
+}
+
+void Host::set_name(const string &n)
+{
+       name=n;
+
+       if(local)
+       {
+               unsigned dot=name.find('.');
+               short_name=name.substr(0, dot);
+       }
+       else
+       {
+               unsigned dot=name.size();
+               for(unsigned i=0; (dot>0 && dot!=string::npos); ++i)
+               {
+                       unsigned prev=name.rfind('.', dot-1);
+                       if(prev+15<name.size() && i>1)
+                               break;
+                       dot=prev;
+               }
+
+               if(dot==string::npos)
+                       short_name=name;
+               else
+                       short_name="..."+name.substr(dot+1);
+       }
+}
+
+void Host::set_local(bool l)
+{
+       local=l;
 }
 
 void Host::set_position(const Vector2 &p)
@@ -26,19 +70,36 @@ void Host::set_position(const Vector2 &p)
        pos=p;
 }
 
-void Host::add_connection(Connection &)
+void Host::set_active(bool a)
+{
+       active=a;
+}
+
+void Host::add_activity(unsigned bytes)
 {
+       activity+=bytes*0.06935;
 }
 
-Connection *Host::get_connection(Host &)
+float Host::send_packet()
 {
-       return 0;
+       float ret=throttle;
+       if(throttle<1)
+               throttle+=0.025;
+       return ret;
 }
 
 void Host::tick(const Msp::Time::TimeDelta &td)
 {
        float dt=td/Msp::Time::sec;
 
+       activity*=pow(0.933f, dt);
+       throttle-=dt;
+       if(throttle<0)
+               throttle=0;
+
+       if(!active)
+               return;
+
        const map<unsigned, Host *> &hosts=netvis.get_hosts();
        float fx=-pos.x*0.1;
        float fy=-pos.y*0.1;
@@ -57,8 +118,8 @@ void Host::tick(const Msp::Time::TimeDelta &td)
                        for(unsigned j=32; (j-- && !((addr^other_addr)>>j));)
                                ++matching_bits;
 
-                       float nearness=24-min(matching_bits, 24U);
-                       float f=10000.0*(1.0/(60+nearness*15)-1.0/d);
+                       float optimal_dist=100+(24-min(matching_bits, 24U))*12;
+                       float f=5000.0*(1.0/optimal_dist-1.0/d);
 
                        fx+=dx/d*f;
                        fy+=dy/d*f;
@@ -73,23 +134,36 @@ void Host::tick(const Msp::Time::TimeDelta &td)
 
 void Host::render() const
 {
+       if(!active)
+               return;
+
        GL::push_matrix();
        GL::translate(static_cast<int>(pos.x), static_cast<int>(pos.y), 0);
 
        GL::Immediate imm((GL::COLOR4_UBYTE, GL::VERTEX2));
        imm.begin(GL::QUADS);
-       imm.color(1.0f, 1.0f, 1.0f, 1.0f);
+       imm.color(1.0f, 1.0f, 1.0f, max(min(static_cast<float>(activity/10000), 1.0f), 0.2f));
        imm.vertex(-5, -5);
        imm.vertex(5, -5);
        imm.vertex(5, 5);
        imm.vertex(-5, 5);
        imm.end();
 
+       GL::pop_matrix();
+}
+
+void Host::render_label() const
+{
+       if(!active)
+               return;
+
        const GL::Font &font=netvis.get_font();
-       GL::translate(-static_cast<int>(font.get_string_width(name)*5), 6, 0);
+
+       GL::push_matrix();
+       GL::translate(static_cast<int>(pos.x)-static_cast<int>(font.get_string_width(short_name)*5), static_cast<int>(pos.y)+6, 0);
        GL::scale_uniform(10);
-       font.draw_string(name);
-       GL::Texture::unbind();
+
+       font.draw_string(short_name);
 
        GL::pop_matrix();
 }
index 60dc5477dadcca1d48ebbd6d93183e83c8accb40..2910ad694577f2412d459d95205cb54c2f415d08 100644 (file)
@@ -1,3 +1,10 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
 #ifndef HOST_H_
 #define HOST_H_
 
@@ -6,7 +13,6 @@
 #include <msp/time/timedelta.h>
 #include "vector2.h"
 
-class Connection;
 class NetVis;
 
 class Host
@@ -15,23 +21,32 @@ private:
        NetVis &netvis;
        unsigned addr;
        std::string name;
+       std::string short_name;
+       bool local;
        Vector2 pos;
-       bool visible;
-       std::map<Host *, Connection *> connections;
+       bool active;
+       float activity;
+       float throttle;
 
 public:
        Host(NetVis &, unsigned);
-       void set_position(const Vector2 &);
        unsigned get_address() const { return addr; }
+       void set_name(const std::string &);
        const std::string &get_name() const { return name; }
+       void set_local(bool);
+
+       void set_position(const Vector2 &);
        const Vector2 &get_position() const { return pos; }
-       bool get_visible() const { return visible; }
 
-       void add_connection(Connection &);
-       Connection *get_connection(Host &);
+       void set_active(bool);
+       bool get_active() const { return active; }
+       void add_activity(unsigned);
+       float get_activity() const { return activity; }
+       float send_packet();
 
        void tick(const Msp::Time::TimeDelta &);
        void render() const;
+       void render_label() const;
 };
 
 #endif
index 711788b86062c6e2d388cd1025cc1d7c350f343e..e49c28ebd9ee798127c15b27183d0979fa1fa042 100644 (file)
@@ -1,9 +1,18 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
 #include <iostream>
+#include <signal.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 #include <linux/if_ether.h>
 #include <msp/core/except.h>
+#include <msp/debug/profilingscope.h>
 #include <msp/gl/immediate.h>
 #include <msp/gl/matrix.h>
 #include <msp/gl/misc.h>
 #include <msp/gl/texture2d.h>
 #include <msp/gl/transform.h>
 #include <msp/strings/formatter.h>
+#include <msp/time/units.h>
 #include <msp/time/utils.h>
 #include "host.h"
 #include "netvis.h"
 #include "packet.h"
+#include "resolver.h"
 
 using namespace std;
 using namespace Msp;
 
-NetVis::NetVis(int /*argc*/, char **argv)
+NetVis::NetVis(int argc, char **argv):
+       draw_labels(true),
+       blend(true),
+       frames(0)
 {
+       if(argc<2)
+               throw UsageError("No interface given");
        iface=argv[1];
 }
 
@@ -34,10 +50,16 @@ int NetVis::main()
        if(pcap_setnonblock(pcap, true, err)==-1)
                throw Exception(err);
 
+       pcap_lookupnet(iface.c_str(), &localnet, &localnet_mask, err);
+       localnet=ntohl(localnet);
+       localnet_mask=ntohl(localnet_mask);
+
        dpy=new Graphics::Display;
        wnd=new Graphics::Window(*dpy, 1024, 768);
        glc=new Graphics::GLContext(*wnd);
        wnd->set_title("NetVis");
+       wnd->signal_close.connect(sigc::bind(sigc::mem_fun(this, &NetVis::exit), 0));
+       wnd->signal_key_press.connect(sigc::mem_fun(this, &NetVis::key_press));
        wnd->show();
 
        GL::enable(GL_BLEND);
@@ -49,83 +71,191 @@ int NetVis::main()
        DataFile::load(*font_tex, "dejavu-10.tex");
        font->set_texture(*font_tex);
 
+       catch_signal(SIGINT);
+
+       resolver=new Resolver;
+
+       //set_loop_mode(TICK_BUSY);
+
        Application::main();
 
+       delete resolver;
+
        delete glc;
        delete wnd;
        delete dpy;
 
+       cout<<hosts.size()+disabled_hosts.size()<<" different hosts seen\n";
+       cout<<"capture: "<<profiler.scope("capture").total_time<<'\n';
+       cout<<"tick:    "<<profiler.scope("tick").total_time<<'\n';
+       cout<<"render:  "<<profiler.scope("render").total_time<<'\n';
+
        return exit_code;
 }
 
 void NetVis::tick()
 {
        Msp::Time::TimeStamp t=Msp::Time::now();
-       if(!last_tick)
-               last_tick=t;
-       Msp::Time::TimeDelta dt=t-last_tick;
-       last_tick=t;
+       Msp::Time::TimeDelta dt;
+       if(tick_t)
+               dt=t-tick_t;
+       tick_t=t;
 
-       dpy->tick();
-
-       pcap_dispatch(pcap, -1, &capture_handler, reinterpret_cast<unsigned char *>(this));
-
-       glClear(GL_COLOR_BUFFER_BIT);
+       if(tick_t>fps_t+Msp::Time::sec)
+       {
+               fps=frames/((tick_t-fps_t)/Msp::Time::sec);
+               fps_t=tick_t;
+               frames=0;
+       }
 
-       GL::matrix_mode(GL::PROJECTION);
-       GL::load_identity();
-       GL::ortho_centered(1024, 768);
-       GL::matrix_mode(GL::MODELVIEW);
-       GL::load_identity();
+       dpy->tick();
 
-       for(map<unsigned, Host *>::iterator i=hosts.begin(); i!=hosts.end(); ++i)
        {
-               i->second->tick(dt);
-               i->second->render();
+               Debug::ProfilingScope s(profiler, "capture");
+               while(pcap_dispatch(pcap, -1, &capture_handler, reinterpret_cast<unsigned char *>(this))>0);
        }
-       for(list<Packet *>::iterator i=packets.begin(); i!=packets.end();)
+
        {
-               (*i)->tick(dt);
-               (*i)->render();
-               if((*i)->get_stale())
+               Debug::ProfilingScope s(profiler, "tick");
+
+               resolver->tick();
+
+               float min_activity=1e7f;
+               for(map<unsigned, Host *>::iterator i=hosts.begin(); i!=hosts.end(); ++i)
+               {
+                       i->second->tick(dt);
+                       min_activity=min(min_activity, i->second->get_activity());
+               }
+               for(map<unsigned, Host *>::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end(); ++i)
+                       i->second->tick(dt);
+
+               for(map<unsigned, Host *>::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end();)
                {
-                       delete *i;
-                       i=packets.erase(i);
+                       if(i->second->get_activity()>min_activity)
+                       {
+                               i->second->set_active(true);
+                               hosts.insert(*i);
+                               disabled_hosts.erase(i++);
+                       }
+                       else
+                               ++i;
+               }
+               if(hosts.size()>20)
+               {
+                       list<float> activity;
+                       for(map<unsigned, Host *>::iterator i=hosts.begin(); i!=hosts.end(); ++i)
+                               activity.push_back(i->second->get_activity());
+                       activity.sort();
+
+                       list<float>::iterator j=activity.begin();
+                       advance(j, activity.size()-20);
+                       float limit=*j;
+
+                       for(map<unsigned, Host *>::iterator i=hosts.begin(); i!=hosts.end();)
+                       {
+                               if(i->second->get_activity()<limit)
+                               {
+                                       i->second->set_active(false);
+                                       disabled_hosts.insert(*i);
+                                       hosts.erase(i++);
+                               }
+                               else
+                                       ++i;
+                       }
+               }
+
+               for(list<Packet *>::iterator i=packets.begin(); i!=packets.end();)
+               {
+                       (*i)->tick(dt);
+                       if((*i)->get_stale())
+                       {
+                               delete *i;
+                               i=packets.erase(i);
+                       }
+                       else
+                               ++i;
                }
-               else
-                       ++i;
        }
 
-       GL::translate(-500, 360, 0);
-       for(map<unsigned, GL::Color>::iterator i=port_colors.begin(); i!=port_colors.end(); ++i)
        {
-               GL::Color &color=i->second;
+               Debug::ProfilingScope s(profiler, "render");
+               glClear(GL_COLOR_BUFFER_BIT);
 
-               GL::push_matrix();
+               GL::matrix_mode(GL::PROJECTION);
+               GL::load_identity();
+               GL::ortho_centered(1024, 768);
+               GL::matrix_mode(GL::MODELVIEW);
+               GL::load_identity();
 
-               GL::Immediate imm((GL::COLOR4_UBYTE,GL::VERTEX2));
-               imm.begin(GL::QUADS);
-               imm.color(color.r, color.g, color.b, color.a);
-               for(float x=0; x<0.5; x+=0.2)
+               for(map<unsigned, Host *>::iterator i=hosts.begin(); i!=hosts.end(); ++i)
+                       i->second->render();
+               if(draw_labels)
                {
-                       imm.vertex(x+0, 0);
-                       imm.vertex(x+10, 0);
-                       imm.vertex(x+10, 10);
-                       imm.vertex(x+0, 10);
+                       glColor4f(1.0, 1.0, 1.0, 1.0);
+                       for(map<unsigned, Host *>::iterator i=hosts.begin(); i!=hosts.end(); ++i)
+                               i->second->render_label();
+                       GL::Texture::unbind();
                }
+               GL::Immediate imm((GL::COLOR4_UBYTE, GL::VERTEX2));
+               imm.begin(GL::QUADS);
+               for(list<Packet *>::iterator i=packets.begin(); i!=packets.end(); ++i)
+                       (*i)->render(imm);
                imm.end();
 
-               GL::translate(15, 1, 0);
+               GL::push_matrix();
+               GL::translate(-500, 360, 0);
+               unsigned n=0;
+               for(map<unsigned, GL::Color>::iterator i=port_colors.begin(); (i!=port_colors.end() && n<20); ++i, ++n)
+               {
+                       GL::Color &color=i->second;
+
+                       imm.begin(GL::QUADS);
+                       imm.color(color.r, color.g, color.b, color.a);
+                       for(unsigned x=0; x<=4; x+=2)
+                       {
+                               imm.vertex(x+0, 0);
+                               imm.vertex(x+10, 0);
+                               imm.vertex(x+10, 10);
+                               imm.vertex(x+0, 10);
+                       }
+                       imm.end();
+
+                       GL::translate(0, -12, 0);
+               }
+               GL::pop_matrix();
+
+               GL::push_matrix();
+               if(draw_labels)
+               {
+                       GL::push_matrix();
+                       GL::translate(-484, 361, 0);
+                       GL::scale_uniform(10);
+                       glColor4f(1.0, 1.0, 1.0, 1.0);
+                       n=0;
+                       for(map<unsigned, GL::Color>::iterator i=port_colors.begin(); (i!=port_colors.end() && n<20); ++i, ++n)
+                       {
+                               font->draw_string(format("%d", i->first));
+
+                               GL::translate(0, -1.2, 0);
+                       }
+                       GL::pop_matrix();
+                       GL::Texture::unbind();
+               }
+               GL::pop_matrix();
+
+               GL::push_matrix();
+               GL::translate(-500, -360, 0);
                GL::scale_uniform(10);
-               glColor4f(1.0, 1.0, 1.0, 1.0);
-               font->draw_string(format("%d", i->first));
+               font->draw_string(format("%d hosts", hosts.size()+disabled_hosts.size()));
+               GL::translate(0, -1.2, 0);
+               font->draw_string(format("%.2f fps", fps));
+               GL::pop_matrix();
                GL::Texture::unbind();
 
-               GL::pop_matrix();
-               GL::translate(0, -12, 0);
+               glc->swap_buffers();
        }
 
-       glc->swap_buffers();
+       ++frames;
 }
 
 Host &NetVis::get_host(unsigned a)
@@ -134,8 +264,15 @@ Host &NetVis::get_host(unsigned a)
        if(i!=hosts.end())
                return *i->second;
 
+       i=disabled_hosts.find(a);
+       if(i!=disabled_hosts.end())
+               return *i->second;
+
        Host *host=new Host(*this, a);
-       host->set_position(Vector2(rand()*30.0/RAND_MAX-15.0, rand()*20.0/RAND_MAX-10.0));
+       if((a&localnet_mask)==localnet)
+               host->set_local(true);
+       resolver->push(host);
+       host->set_position(Vector2(rand()*400.0/RAND_MAX-200.0, rand()*400.0/RAND_MAX-200.0));
        hosts[a]=host;
        return *host;
 }
@@ -159,6 +296,17 @@ GL::Color &NetVis::get_port_color(unsigned port)
        return port_colors[port]=color;
 }
 
+void NetVis::key_press(unsigned key, unsigned, wchar_t)
+{
+       if(key==46)
+               draw_labels=!draw_labels;
+       else if(key==56)
+       {
+               blend=!blend;
+               GL::set(GL_BLEND, blend);
+       }
+}
+
 void NetVis::capture_handler(unsigned char *user, const pcap_pkthdr *, const unsigned char *data)
 {
        NetVis *self=reinterpret_cast<NetVis *>(user);
@@ -168,8 +316,7 @@ void NetVis::capture_handler(unsigned char *user, const pcap_pkthdr *, const uns
        {
                const iphdr *ip=reinterpret_cast<const iphdr *>(eth+1);
 
-               //cout<<"IP packet of "<<hdr->len<<'/'<<ntohs(ip->tot_len)<<" bytes\n";
-
+               unsigned size=ntohs(ip->tot_len);
                unsigned port=0;
                if(ip->protocol==IPPROTO_TCP)
                {
@@ -185,8 +332,23 @@ void NetVis::capture_handler(unsigned char *user, const pcap_pkthdr *, const uns
                Host *dhost=0;
                if((ntohl(ip->daddr)&0xFF)!=0xFF)
                        dhost=&self->get_host(ntohl(ip->daddr));
-               self->packets.push_back(new Packet(shost, dhost, self->get_port_color(port), ntohs(ip->tot_len)));
+
+               float throttle=shost.send_packet();
+               if(throttle<1)
+               {
+                       self->packets.push_back(new Packet(shost, dhost, self->get_port_color(port), size));
+                       self->packets.back()->tick(-throttle*Msp::Time::sec);
+               }
+
+               shost.add_activity(size);
+               if(dhost)
+                       dhost->add_activity(size);
        }
 }
 
+void NetVis::sighandler(int)
+{
+       exit(0);
+}
+
 Application::RegApp<NetVis> NetVis::reg;
index daec1cfade0116cbfa08b5632e253752b81ba8e1..9e8661e58307c43ed9efe5d289fcb1e9eaacde8a 100644 (file)
@@ -1,3 +1,10 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
 #ifndef NETVIS_H_
 #define NETVIS_H_
 
@@ -5,6 +12,7 @@
 #include <map>
 #include <pcap.h>
 #include <msp/core/application.h>
+#include <msp/debug/profiler.h>
 #include <msp/gbase/display.h>
 #include <msp/gbase/glcontext.h>
 #include <msp/gbase/window.h>
@@ -12,8 +20,9 @@
 #include <msp/gl/font.h>
 #include <msp/time/timestamp.h>
 
-class Packet;
 class Host;
+class Packet;
+class Resolver;
 
 class NetVis: public Msp::Application
 {
@@ -22,13 +31,23 @@ private:
        pcap_t *pcap;
        std::list<Packet *> packets;
        std::map<unsigned, Host *> hosts;
+       std::map<unsigned, Host *> disabled_hosts;
        Msp::Graphics::Display *dpy;
        Msp::Graphics::Window *wnd;
        Msp::Graphics::GLContext *glc;
-       Msp::Time::TimeStamp last_tick;
+       Msp::Time::TimeStamp tick_t;
        std::map<unsigned, Msp::GL::Color> port_colors;
        Msp::GL::Font *font;
        Msp::GL::Texture2D *font_tex;
+       Msp::Debug::Profiler profiler;
+       bool draw_labels;
+       bool blend;
+       Resolver *resolver;
+       unsigned localnet;
+       unsigned localnet_mask;
+       Msp::Time::TimeStamp fps_t;
+       unsigned frames;
+       float fps;
 
 public:
        NetVis(int, char **);
@@ -39,9 +58,12 @@ private:
        virtual void tick();
        Host &get_host(unsigned);
        Msp::GL::Color &get_port_color(unsigned);
+       void key_press(unsigned, unsigned, wchar_t);
 
        static void capture_handler(unsigned char *, const pcap_pkthdr *, const unsigned char *);
 
+       void sighandler(int);
+
        static Application::RegApp<NetVis> reg;
 };
 
index 491e8076245bee11bb81aa49825db1a4e45f5997..512144a9517414bfd18576c0b9a18478392c0db3 100644 (file)
@@ -1,3 +1,10 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
 #include <cmath>
 #include <msp/gl/immediate.h>
 #include <msp/gl/matrix.h>
@@ -13,11 +20,10 @@ Packet::Packet(const Host &s, const Host *d, const GL::Color &c, unsigned i):
        dest(d),
        color(c),
        x(0),
-       size(cbrt(i)),
-       angle(rand()*180.0/RAND_MAX),
-       rspeed(rand()*180.0/RAND_MAX-90.0)
-{
-}
+       size(cbrt(i)*1.5),
+       angle(rand()*M_PI*2/RAND_MAX),
+       rspeed(rand()*M_PI/RAND_MAX-M_PI/2)
+{ }
 
 void Packet::tick(const Time::TimeDelta &dt)
 {
@@ -27,46 +33,47 @@ void Packet::tick(const Time::TimeDelta &dt)
                x=1;
        angle+=rspeed*f;
        if(angle<0)
-               angle+=360;
-       if(angle>=360)
-               angle-=360;
+               angle+=M_PI*2;
+       if(angle>=M_PI*2)
+               angle-=M_PI;
 }
 
-void Packet::render() const
+void Packet::render(GL::PrimitiveBuilder &bld) const
 {
-       GL::push_matrix();
+       if(x<0)
+               return;
+       if(!src.get_active() || (dest && !dest->get_active()))
+               return;
 
        const Vector2 &spos=src.get_position();
 
        if(dest)
        {
                const Vector2 &dpos=dest->get_position();
-               GL::translate(spos.x*(1-x)+dpos.x*x, spos.y*(1-x)+dpos.y*x, 0);
-               GL::rotate(angle, 0, 0, 1);
+               Vector2 pos(spos.x*(1-x)+dpos.x*x, spos.y*(1-x)+dpos.y*x);
+               Vector2 corner(cos(angle)*size, sin(angle)*size);
 
-               GL::Immediate imm((GL::COLOR4_UBYTE,GL::VERTEX2));
-               imm.begin(GL::QUADS);
-               imm.color(color.r, color.g, color.b, color.a);
-               imm.vertex(-size, -size);
-               imm.vertex(size, -size);
-               imm.vertex(size, size);
-               imm.vertex(-size, size);
-               imm.end();
+               if(bld.get_type()!=GL::QUADS)
+               {
+                       bld.end();
+                       bld.begin(GL::QUADS);
+               }
+               bld.color(color.r, color.g, color.b, color.a);
+               bld.vertex(pos.x+corner.x, pos.y+corner.y);
+               bld.vertex(pos.x-corner.y, pos.y+corner.x);
+               bld.vertex(pos.x-corner.x, pos.y-corner.y);
+               bld.vertex(pos.x+corner.y, pos.y-corner.x);
        }
        else
        {
-               GL::translate(spos.x, spos.y, 0);
-               GL::Immediate imm((GL::COLOR4_UBYTE,GL::VERTEX2));
-               imm.begin(GL::TRIANGLE_FAN);
-               imm.color(color.r, color.g, color.b, color.a*(1-x));
-               imm.vertex(0, 0);
+               bld.end();
+               bld.begin(GL::TRIANGLE_FAN);
+               bld.color(color.r, color.g, color.b, color.a*(1-x));
+               bld.vertex(spos.x, spos.y);
                for(unsigned i=0; i<=24; ++i)
                {
                        float a=i*M_PI/12;
-                       imm.vertex(cos(a)*x*200, sin(a)*x*200);
+                       bld.vertex(spos.x+cos(a)*x*200, spos.y+sin(a)*x*200);
                }
-               imm.end();
        }
-
-       GL::pop_matrix();
 }
index cfeb2dfbeb8f66ce18f01e423cd705df6124e460..18e7e4355f82e478c3435465f4f4ce9a1e96c45e 100644 (file)
@@ -1,3 +1,10 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
 #ifndef PACKET_H_
 #define PACKET_H_
 
@@ -21,7 +28,7 @@ public:
        Packet(const Host &, const Host *, const Msp::GL::Color &, unsigned);
        bool get_stale() const { return x>=1; }
        void tick(const Msp::Time::TimeDelta &);
-       void render() const;
+       void render(Msp::GL::PrimitiveBuilder &) const;
 };
 
 #endif
diff --git a/source/resolver.cpp b/source/resolver.cpp
new file mode 100644 (file)
index 0000000..1a0b99f
--- /dev/null
@@ -0,0 +1,75 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
+#include <netinet/in.h>
+#include <netdb.h>
+#include <msp/time/units.h>
+#include <msp/time/utils.h>
+#include "host.h"
+#include "resolver.h"
+
+using namespace std;
+using namespace Msp;
+
+Resolver::Resolver():
+       done(false)
+{
+       launch();
+}
+
+Resolver::~Resolver()
+{
+       done=true;
+       join();
+}
+
+void Resolver::push(Host *h)
+{
+       MutexLock l_(mutex);
+
+       in_queue.push_back(h);
+}
+
+void Resolver::tick()
+{
+       MutexLock l_(mutex);
+
+       for(list<Result>::iterator i=out_queue.begin(); i!=out_queue.end(); ++i)
+               i->host->set_name(i->name);
+       out_queue.clear();
+}
+
+void Resolver::main()
+{
+       while(!done)
+       {
+               while(1)
+               {
+                       Host *host;
+                       {
+                               MutexLock l_(mutex);
+                               if(in_queue.empty())
+                                       break;
+                               host=in_queue.front();
+                               in_queue.erase(in_queue.begin());
+                       }
+                       
+                       sockaddr_in addr;
+                       addr.sin_family=AF_INET;
+                       addr.sin_addr.s_addr=htonl(host->get_address());
+                       char buf[128];
+                       int err=getnameinfo(reinterpret_cast<sockaddr *>(&addr), sizeof(addr), buf, sizeof(buf), 0, 0, NI_NOFQDN|NI_NAMEREQD);
+                       if(err==0)
+                       {
+                               MutexLock l_(mutex);
+                               out_queue.push_back(Result(host, buf));
+                       }
+               }
+
+               Time::sleep(Time::sec);
+       }
+}
diff --git a/source/resolver.h b/source/resolver.h
new file mode 100644 (file)
index 0000000..fb9dd10
--- /dev/null
@@ -0,0 +1,43 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
+#ifndef RESOLVER_H_
+#define RESOLVER_H_
+
+#include <list>
+#include <msp/core/mutex.h>
+#include <msp/core/thread.h>
+
+class Host;
+
+class Resolver: public Msp::Thread
+{
+private:
+       struct Result
+       {
+               Host *host;
+               std::string name;
+
+               Result(Host *h, const std::string &n): host(h), name(n) { }
+       };
+
+       std::list<Host *> in_queue;
+       std::list<Result> out_queue;
+       Msp::Mutex mutex;
+       bool done;
+
+public:
+       Resolver();
+       ~Resolver();
+
+       void push(Host *);
+       void tick();
+private:
+       void main();
+};
+
+#endif
index 0ff927c25ee6bd9e5d55cab199be8d2a204867ab..8ece3b286ad1cefca3bbb072b0ac1395b6149483 100644 (file)
@@ -1,3 +1,10 @@
+/* $Id$
+
+This file is part of NetVis
+Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
+Distributed unter the GPL
+*/
+
 #ifndef VECTOR2_H_
 #define VECTOR2_H_