summaryrefslogtreecommitdiff
path: root/lib/server/Socket.cpp
blob: 0343b8bf1046824ced57a80412ba5878b68ddb69 (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// --------------------------------------------------------------------------
//
// File
//		Name:    Socket.cpp
//		Purpose: Socket related stuff
//		Created: 2003/07/31
//
// --------------------------------------------------------------------------

#include "Box.h"

#include <unistd.h>
#include <sys/types.h>
#ifndef WIN32
#include <sys/socket.h>
#include <netdb.h>
#include <syslog.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

#include <string.h>
#include <stdio.h>

#include "Socket.h"
#include "ServerException.h"

#include "MemLeakFindOn.h"

// --------------------------------------------------------------------------
//
// Function
//		Name:    Socket::NameLookupToSockAddr(SocketAllAddr &, int, char *, int)
//		Purpose: Sets up a sockaddr structure given a name and type
//		Created: 2003/07/31
//
// --------------------------------------------------------------------------
void Socket::NameLookupToSockAddr(SocketAllAddr &addr, int &sockDomain, int Type, const char *Name, int Port, int &rSockAddrLenOut)
{
	int sockAddrLen = 0;

	switch(Type)
	{
	case TypeINET:
		sockDomain = AF_INET;
		{
			// Lookup hostname
			struct hostent *phost = ::gethostbyname(Name);
			if(phost != NULL)
			{
				if(phost->h_addr_list[0] != 0)
				{
					sockAddrLen = sizeof(addr.sa_inet);
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
					addr.sa_inet.sin_len = sizeof(addr.sa_inet);
#endif
					addr.sa_inet.sin_family = PF_INET;
					addr.sa_inet.sin_port = htons(Port);
					addr.sa_inet.sin_addr = *((in_addr*)phost->h_addr_list[0]);
					for(unsigned int l = 0; l < sizeof(addr.sa_inet.sin_zero); ++l)
					{
						addr.sa_inet.sin_zero[l] = 0;
					}
				}
				else
				{
					THROW_EXCEPTION(ConnectionException, Conn_SocketNameLookupError);
				}
			}
			else
			{
				THROW_EXCEPTION(ConnectionException, Conn_SocketNameLookupError);
			}
		}
		break;
	
#ifndef WIN32
	case TypeUNIX:
		sockDomain = AF_UNIX;
		{
			// Check length of name is OK
			unsigned int nameLen = ::strlen(Name);
			if(nameLen >= (sizeof(addr.sa_unix.sun_path) - 1))
			{
				THROW_EXCEPTION(ServerException, SocketNameUNIXPathTooLong);
			}
			sockAddrLen = nameLen + (((char*)(&(addr.sa_unix.sun_path[0]))) - ((char*)(&addr.sa_unix)));
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
			addr.sa_unix.sun_len = sockAddrLen;
#endif
			addr.sa_unix.sun_family = PF_UNIX;
			::strcpy(addr.sa_unix.sun_path, Name);
		}
		break;
#endif
	
	default:
		THROW_EXCEPTION(CommonException, BadArguments)
		break;
	}
	
	// Return size of structure to caller
	rSockAddrLenOut = sockAddrLen;
}




// --------------------------------------------------------------------------
//
// Function
//		Name:    Socket::LogIncomingConnection(const struct sockaddr *, socklen_t)
//		Purpose: Writes a message logging the connection to syslog
//		Created: 2003/08/01
//
// --------------------------------------------------------------------------
void Socket::LogIncomingConnection(const struct sockaddr *addr, socklen_t addrlen)
{
	if(addr == NULL) {THROW_EXCEPTION(CommonException, BadArguments)}

	switch(addr->sa_family)
	{
	case AF_UNIX:
		::syslog(LOG_INFO, "Incoming connection from local (UNIX socket)");
		break;		
	
	case AF_INET:
		{
			sockaddr_in *a = (sockaddr_in*)addr;
			::syslog(LOG_INFO, "Incoming connection from %s port %d", inet_ntoa(a->sin_addr), ntohs(a->sin_port));
		}
		break;		
	
	default:
		::syslog(LOG_INFO, "Incoming connection of unknown type");
		break;
	}
}

// --------------------------------------------------------------------------
//
// Function
//		Name:    Socket::IncomingConnectionLogMessage(const struct sockaddr *, socklen_t)
//		Purpose: Returns a string for use in log messages
//		Created: 2003/08/01
//
// --------------------------------------------------------------------------
std::string Socket::IncomingConnectionLogMessage(const struct sockaddr *addr, socklen_t addrlen)
{
	if(addr == NULL) {THROW_EXCEPTION(CommonException, BadArguments)}

	switch(addr->sa_family)
	{
	case AF_UNIX:
		return std::string("Incoming connection from local (UNIX socket)");
		break;		
	
	case AF_INET:
		{
			char msg[256];	// more than enough
			sockaddr_in *a = (sockaddr_in*)addr;
			sprintf(msg, "Incoming connection from %s port %d", inet_ntoa(a->sin_addr), ntohs(a->sin_port));
			return std::string(msg);
		}
		break;		
	
	default:
		return std::string("Incoming connection of unknown type");
		break;
	}
	
	// Dummy.
	return std::string();
}