-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaddress.cpp
More file actions
114 lines (105 loc) · 2.72 KB
/
address.cpp
File metadata and controls
114 lines (105 loc) · 2.72 KB
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>
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 ] );
}