summaryrefslogtreecommitdiff
path: root/src/mt/lookup.cc
blob: c0e72c8ef3c4101568d06a1bb2e79ff7253deb12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*************************************************************************
 *
 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <mt/lookup.h>
#include <mt/mvec.h>
#include <mt/lock.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

const time_t VALIDSEC=120;
static msvec<IPnode> cache;
static mutex_t mutex;

int Lookup(IPnode& node,const in_addr& ia)
{
  MLOCK(mutex);
  IPnode* p=cache.begin();
  time_t now=time(0);
  while(p<cache.end()) {
    if(now>p->valid) cache.erase(p);
    else if(memcmp(&p->addr,&ia,sizeof(ia))==0) {p->valid=now+VALIDSEC;node=*p;return 1;}
    else p++;
  }
  hostent hent;
  sref_t buf;
  int herr;
  hostent* hp=0;
  gethostbyaddr_r((const char*)&ia,sizeof(ia),AF_INET,
                  &hent,
                  buf,sizeof(sref_t),
                  &hp,
                  &herr);
  if(!hp) return 0;
  memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length));
  node.ip=inet_ntoa(node.addr);
  node.name=hp->h_name;
  node.valid=now+VALIDSEC;
  cache.push_back(node);
  return 1;
}

int Lookup(IPnode& node,const sref& s)
{
  MLOCK(mutex);
  IPnode* p=cache.begin();
  time_t now=time(0);
  while(p<cache.end()) {
    if(now>p->valid) cache.erase(p);
    else if(p->ip==s||p->name==s) { p->valid=now+VALIDSEC; node=*p; return 1; }
    else p++;
  }
  hostent hent;
  sref_t sbuf,buf;
  int herr;
  hostent* hp=0;
  for(int i=0;s[i];i++) if(s[i]!='.'&&(s[i]<'0'||s[i]>'9')) {
    gethostbyname_r(s.copyto(sbuf),&hent,buf,sizeof(sref_t),&hp,&herr);
    break;
  }
  if(!hp) {
    unsigned long a=inet_addr(s.copyto(buf));
    gethostbyaddr_r((char*)&a,sizeof(a),AF_INET,&hent,buf,sizeof(sref_t),&hp,&herr);
  }
  if(!hp) return 0;
  memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length));
  node.ip=inet_ntoa(node.addr);
  node.name=hp->h_name;
  node.valid=now+VALIDSEC;
  cache.push_back(node);
  return 1;
}