File: address.cpp

package info (click to toggle)
postal 0.76%2Bnmu2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 552 kB
  • sloc: cpp: 4,201; sh: 289; ansic: 259; makefile: 136
file content (114 lines) | stat: -rw-r--r-- 2,322 bytes parent folder | download | duplicates (6)
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "address.h"
#include <cstring>
#include <stdio.h>
#include <cstdlib>
#include <netdb.h>
#include <sys/socket.h>

typedef char *PCHAR;

address::address(const char *addr, unsigned short default_port)
{
  unsigned short port = default_port;
  char *addr_copy = strdup(addr);
  int len = strlen(addr);
  m_count = 1;
  int i;
  for(i = 0; i < len; i++)
  {
    if(addr_copy[i] == ',')
      m_count++;
  }
  char **names = (char **)malloc(m_count * sizeof(char *));
  int ind = 0;
  for(i = 0; i < m_count; i++)
  {
    names[i] = &addr_copy[ind];
    while(addr_copy[ind] && addr_copy[ind] != ',')
      ind++;
    addr_copy[ind] = '\0';
    ind++;
  }
  m_rr_dns = (bool *)malloc(m_count * sizeof(bool));
  m_addr = (sockaddr_in *)malloc(m_count * sizeof(sockaddr_in));
  m_hostname = (char **)malloc(m_count * sizeof(char *));
  for(i = 0; i < m_count; i++)
  {
    char *hostname = names[i];
    if(hostname[0] == '+')
    {
      m_rr_dns[i] = true;
      hostname++;
    }
    else
    {
      m_rr_dns[i] = false;
    }
    if(hostname[0] == '[')
    {
      hostname++;
      int j;
      for(j = 0; hostname[j] && hostname[j] != ']'; j++)
        {}
 
      if(!hostname[j])
      {
        fprintf(stderr, "Bad address: %s\n", addr);
        exit(1);
      }
      hostname[j] = '\0';
      port = atoi(&hostname[j + 1]);
    }
    m_hostname[i] = strdup(hostname);
    m_addr[i].sin_family = AF_INET;
    m_addr[i].sin_port = htons(port);
    if(!m_rr_dns[i])
    {
      if(resolve_name(i))
        exit(1);
    }
  }
  free(names);
  free(addr_copy);
}

address::~address()
{
  for(int i = 0; i < m_count; i++)
    free(m_hostname[i]);
  free(m_hostname);
  free(m_rr_dns);
  free(m_addr);
}

int address::resolve_name(int ind)
{
  hostent *he = gethostbyname(m_hostname[ind]);
  if(!he)
  {
    fprintf(stderr, "Bad address \"%s\" for server.\n", m_hostname[ind]);
    return 1;
  }
  m_addr[ind].sin_addr.s_addr = *((unsigned int *)he->h_addr_list[0]);
  return 0;
}

sockaddr *address::get_rand_addr()
{
  int ind = 0;
  if(m_count > 1)
    ind = rand() % m_count;
  return get_addr(ind);
}

sockaddr *address::get_addr(int ind)
{
  if(ind < 0 || ind > m_count)
    return get_rand_addr();
  if(m_rr_dns[ind])
  {
    if(resolve_name(ind))
      return NULL;
  }
  return (sockaddr *)&m_addr[ind];
}