summaryrefslogtreecommitdiff
path: root/src/network/core/address.h
blob: 7488aad3f7d75828997cf5702796ec68b40a2a1b (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
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
115
116
117
118
119
120
121
122
123
124
/* $Id$ */

/** @file core/address.h Wrapper for network addresses. */

#ifndef NETWORK_ADDRESS_H
#define NETWORK_ADDRESS_H

#ifdef ENABLE_NETWORK

#include "os_abstraction.h"

/**
 * Wrapper for (un)resolved network addresses; there's no reason to transform
 * a numeric IP to a string and then back again to pass it to functions. It
 * furthermore allows easier delaying of the hostname lookup.
 */
class NetworkAddress {
private:
	bool resolved;            ///< Has the IP address been resolved
	char *hostname;           ///< The hostname, NULL if there isn't one
	sockaddr_storage address; ///< The resolved address

public:
	/**
	 * Create a network address based on a resolved IP and port
	 * @param ip the resolved ip
	 * @param port the port
	 */
	NetworkAddress(in_addr_t ip, uint16 port) :
		resolved(true),
		hostname(NULL)
	{
		memset(&this->address, 0, sizeof(this->address));
		this->address.ss_family = AF_INET;
		((struct sockaddr_in*)&this->address)->sin_addr.s_addr = ip;
		((struct sockaddr_in*)&this->address)->sin_port = htons(port);
	}

	/**
	 * Create a network address based on a resolved IP and port
	 * @param address the IP address with port
	 */
	NetworkAddress(struct sockaddr_storage &address) :
		resolved(true),
		hostname(NULL),
		address(address)
	{
	}

	/**
	 * Create a network address based on a unresolved host and port
	 * @param ip the unresolved hostname
	 * @param port the port
	 */
	NetworkAddress(const char *hostname = NULL, uint16 port = 0) :
		resolved(false),
		hostname(hostname == NULL ? NULL : strdup(hostname))
	{
		memset(&this->address, 0, sizeof(this->address));
		this->address.ss_family = AF_INET;
		((struct sockaddr_in*)&this->address)->sin_port = htons(port);
	}

	/**
	 * Make a clone of another address
	 * @param address the address to clone
	 */
	NetworkAddress(const NetworkAddress &address) :
		resolved(address.resolved),
		hostname(address.hostname == NULL ? NULL : strdup(address.hostname)),
		address(address.address)
	{
	}

	/** Clean up our mess */
	~NetworkAddress()
	{
		free(hostname);
	}

	/**
	 * Get the hostname; in case it wasn't given the
	 * IPv4 dotted representation is given.
	 * @return the hostname
	 */
	const char *GetHostname();

	/**
	 * Get the address as a string, e.g. 127.0.0.1:12345.
	 * @return the address
	 */
	const char *GetAddressAsString();

	/**
	 * Get the address in it's internal representation.
	 * @return the address
	 */
	const sockaddr_storage *GetAddress();

	/**
	 * Get the IP address. If the IP has not been resolved yet this will resolve
	 * it possibly blocking this function for a while
	 * @return the IP address
	 */
	uint32 GetIP();

	/**
	 * Get the port
	 * @return the port
	 */
	uint16 GetPort() const;

	/**
	 * Check whether the IP address has been resolved already
	 * @return true iff the port has been resolved
	 */
	bool IsResolved() const
	{
		return this->resolved;
	}
};

#endif /* ENABLE_NETWORK */
#endif /* NETWORK_ADDRESS_H */