gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
socket.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * 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;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Authors: Nathan Binkert
29  */
30 
31 #include "base/socket.hh"
32 
33 #include <netinet/in.h>
34 #include <netinet/tcp.h>
35 #include <sys/socket.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38 
39 #include <cerrno>
40 
41 #include "base/misc.hh"
42 #include "base/types.hh"
43 #include "sim/byteswap.hh"
44 
45 using namespace std;
46 
48 bool ListenSocket::anyListening = false;
49 
50 bool ListenSocket::bindToLoopback = false;
51 
52 void
54 {
55  if (anyListening)
56  panic("Too late to disable all listeners, already have a listener");
57  listeningDisabled = true;
58 }
59 
60 bool
62 {
63  return listeningDisabled;
64 }
65 
66 void
68 {
69  if (anyListening)
70  panic("Too late to bind to loopback, already have a listener");
71  bindToLoopback = true;
72 }
73 
75 //
76 //
77 
79  : listening(false), fd(-1)
80 {}
81 
83 {
84  if (fd != -1)
85  close(fd);
86 }
87 
88 // Create a socket and configure it for listening
89 bool
90 ListenSocket::listen(int port, bool reuse)
91 {
92  if (listening)
93  panic("Socket already listening!");
94 
95  fd = ::socket(PF_INET, SOCK_STREAM, 0);
96  if (fd < 0)
97  panic("Can't create socket:%s !", strerror(errno));
98 
99  if (reuse) {
100  int i = 1;
101  if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&i,
102  sizeof(i)) < 0)
103  panic("ListenSocket(listen): setsockopt() SO_REUSEADDR failed!");
104  }
105 
106  struct sockaddr_in sockaddr;
107  sockaddr.sin_family = PF_INET;
108  sockaddr.sin_addr.s_addr =
109  htobe<unsigned long>(bindToLoopback ? INADDR_LOOPBACK : INADDR_ANY);
110  sockaddr.sin_port = htons(port);
111  // finally clear sin_zero
112  memset(&sockaddr.sin_zero, 0, sizeof(sockaddr.sin_zero));
113  int ret = ::bind(fd, (struct sockaddr *)&sockaddr, sizeof (sockaddr));
114  if (ret != 0) {
115  if (ret == -1 && errno != EADDRINUSE)
116  panic("ListenSocket(listen): bind() failed!");
117  return false;
118  }
119 
120  if (::listen(fd, 1) == -1) {
121  if (errno != EADDRINUSE)
122  panic("ListenSocket(listen): listen() failed!");
123 
124  return false;
125  }
126 
127  listening = true;
128  anyListening = true;
129  return true;
130 }
131 
132 
133 // Open a connection. Accept will block, so if you don't want it to,
134 // make sure a connection is ready before you call accept.
135 int
136 ListenSocket::accept(bool nodelay)
137 {
138  struct sockaddr_in sockaddr;
139  socklen_t slen = sizeof (sockaddr);
140  int sfd = ::accept(fd, (struct sockaddr *)&sockaddr, &slen);
141  if (sfd != -1 && nodelay) {
142  int i = 1;
143  if (::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (char *)&i,
144  sizeof(i)) < 0)
145  warn("ListenSocket(accept): setsockopt() TCP_NODELAY failed!");
146  }
147 
148  return sfd;
149 }
virtual ~ListenSocket()
Definition: socket.cc:82
virtual bool listen(int port, bool reuse=true)
Definition: socket.cc:90
Bitfield< 7 > i
Definition: miscregs.hh:1378
#define panic(...)
Definition: misc.hh:153
ListenSocket()
Definition: socket.cc:78
static bool bindToLoopback
Definition: socket.hh:40
#define warn(...)
Definition: misc.hh:219
static bool allDisabled()
Definition: socket.cc:61
static void loopbackOnly()
Definition: socket.cc:67
virtual int accept(bool nodelay=false)
Definition: socket.cc:136
static bool anyListening
Definition: socket.hh:38
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
static void disableAll()
Definition: socket.cc:53
bool listening
Definition: socket.hh:49
static bool listeningDisabled
Definition: socket.hh:37
Bitfield< 14, 12 > fd
Definition: types.hh:155

Generated on Fri Jun 9 2017 13:03:41 for gem5 by doxygen 1.8.6