1
// Copyright (c) 2002 Rob Kaper <rob@unixcode.org>. All rights reserved.
3
// Redistribution and use in source and binary forms, with or without
4
// modification, are permitted provided that the following conditions
7
// 1. Redistributions of source code must retain the above copyright
8
// notice, this list of conditions and the following disclaimer.
9
// 2. Redistributions in binary form must reproduce the above copyright
10
// notice, this list of conditions and the following disclaimer in the
11
// documentation and/or other materials provided with the distribution.
13
// THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS'' AND
14
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
// ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
#include <sys/types.h>
26
#include <sys/socket.h>
27
#include <arpa/inet.h>
28
#include <netinet/in.h>
35
#include "listenport.h"
40
#define inet_pton(a, b, c) inet_aton(b, c)
45
ListenPort::ListenPort(sa_family_t family, const std::string ip, const int port)
50
m_fd = socket(family, SOCK_STREAM, 0);
55
struct sockaddr_storage servaddr;
56
memset(&servaddr, 0, sizeof(servaddr));
57
servaddr.ss_family = family;
58
if(family == AF_INET) {
59
struct sockaddr_in *servaddr_in = (struct sockaddr_in *)&servaddr;
60
inet_pton(AF_INET, m_ipAddr.c_str(), &(servaddr_in->sin_addr));
61
servaddr_in->sin_port = htons(m_port);
62
} else if (family == AF_INET6) {
63
struct sockaddr_in6 *servaddr_in6 = (struct sockaddr_in6 *)&servaddr;
64
inet_pton(AF_INET6, m_ipAddr.c_str(), &(servaddr_in6->sin6_addr));
65
servaddr_in6->sin6_port = htons(m_port);
67
// bind on IPv6 only if possible
69
setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only));
75
// release the socket after program crash, avoid TIME_WAIT
77
if(setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
83
if( (bind(m_fd, (struct sockaddr *) &servaddr, sizeof(servaddr))) == -1)
90
if(listen(m_fd, LISTENQ) == -1)
96
// get current socket flags
98
if ((flags=fcntl(m_fd, F_GETFL)) == -1)
101
// set socket to non-blocking
103
if (fcntl(m_fd, F_SETFL, flags) == -1)
107
ListenPort::ListenPort(int fd) {
113
// get current socket flags
115
if ((flags=fcntl(m_fd, F_GETFL)) == -1)
118
// set socket to non-blocking
120
if (fcntl(m_fd, F_SETFL, flags) == -1)
124
bool ListenPort::isBound() const