1 /****************************************************************************
2 * Copyright (C) 2006-2008 by Jason Ansel *
3 * jansel@csail.mit.edu *
4 * *
5 * This file is part of the JALIB module of DMTCP (DMTCP:dmtcp/jalib). *
6 * *
7 * DMTCP:dmtcp/jalib is free software: you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public License as *
9 * published by the Free Software Foundation, either version 3 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * DMTCP:dmtcp/src is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with DMTCP:dmtcp/src. If not, see *
19 * <http://www.gnu.org/licenses/>. *
20 ****************************************************************************/
21
22 #ifndef JALIBJSOCKET_H
23 #define JALIBJSOCKET_H
24
25 #include "stlwrapper.h"
26 #include "jalloc.h"
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <vector>
31 #include "jassert.h"
32 #include <errno.h>
33 #include <sys/time.h>
34 #include <time.h>
35
36 namespace jalib
37 {
38
39 class JSocket;
40
41 class JSockAddr
42 {
43 friend class JSocket;
44 public:
45 #ifdef JALIB_ALLOCATOR
46 static void* operator new(size_t nbytes, void* p) { return p; }
47 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
48 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
49 #endif
50 JSockAddr ( const char* hostname = NULL );
51 static const JSockAddr ANY;
52 const struct sockaddr_in* addr() const{return &_addr;}
53 socklen_t addrlen() const{return sizeof ( sockaddr_in );}
54 private:
55 struct sockaddr_in _addr;
56 };
57
58
59 class JSocket
60 {
61 public:
62 #ifdef JALIB_ALLOCATOR
63 static void* operator new(size_t nbytes, void* p) { return p; }
64 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
65 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
66 #endif
67 ///
68 /// Create new socket
69 protected: JSocket(); public:
70 //so we don't leak FDs
71 inline static JSocket Create() { return JSocket(); }
72 ///
73 /// Use existing socket
74 JSocket ( int fd ) : _sockfd ( fd ) {}
75
76 bool connect ( const JSockAddr& addr, int port );
77 bool connect ( const struct sockaddr *addr, socklen_t addrlen, int port );
78 bool bind ( const JSockAddr& addr, int port );
79 bool bind ( const struct sockaddr *addr, socklen_t addrlen );
80 bool listen ( int backlog = 32 );
81 JSocket accept ( struct sockaddr_storage* remoteAddr = NULL,socklen_t* remoteLen = NULL );
82 bool close();
83 ssize_t read ( char* buf, size_t len );
84 ssize_t write ( const char* buf, size_t len );
85 ssize_t readAll ( char* buf, size_t len );
86 ssize_t writeAll ( const char* buf, size_t len );
87 bool isValid() const;
88
89 void enablePortReuse();
90
91 template <typename T>
92 JSocket& operator << ( const T& t ) { writeAll ( ( const char* ) &t, sizeof ( T ) ); return *this; }
93 template <typename T>
|
Event tainted_data_argument: |
Calling function "jalib::JSocket::readAll(char *, unsigned long)" taints parameter "*((char *)t)". [details] |
94 JSocket& operator >> ( T& t ) { readAll ( ( char* ) &t, sizeof ( T ) ); return *this; }
95
96 int sockfd() const { return _sockfd; }
97 // If socket originally bound to port 0, we need this to find actual port
98 int port() const { struct sockaddr_in addr;
99 socklen_t addrlen = sizeof(addr);
100 if (-1 == getsockname(_sockfd,
101 (struct sockaddr *)&addr, &addrlen))
102 return -1;
103 else
104 return (int)ntohs(addr.sin_port);
105 }
106 operator int () { return _sockfd; }
107 void changeFd ( int newFd );
108 protected:
109 int _sockfd;
110 };
111
112 class JClientSocket : public JSocket
113 {
114 public:
115 JClientSocket ( const JSockAddr& addr, int port )
116 {
117 if ( !connect ( addr, port ) )
118 close();
119 }
120 };
121
122 class JServerSocket : public JSocket
123 {
124 public:
125 JServerSocket ( int sockfd )
126 : JSocket ( sockfd )
127 {
128 enablePortReuse();
129 }
130
131 JServerSocket ( const JSockAddr& addr, int port, int backlog = 32 )
132 {
133 enablePortReuse();
134 if ( !bind ( addr, port ) || !listen ( backlog ) )
135 close();
136 }
137 };
138
139 class JReaderInterface
140 {
141 public:
142 #ifdef JALIB_ALLOCATOR
143 static void* operator new(size_t nbytes, void* p) { return p; }
144 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
145 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
146 #endif
147 JReaderInterface ( JSocket& sock ) :_sock ( sock ) {}
148 virtual ~JReaderInterface() {}
149 virtual bool readOnce() = 0;
150 virtual bool hadError() const = 0;
151 virtual void reset() = 0;
152 virtual bool ready() const = 0;
153 virtual const char* buffer() const = 0;
154 virtual int bytesRead() const = 0;
155
156 const JSocket& socket() const{ return _sock; }
157 JSocket& socket() { return _sock; }
158 protected:
159 JSocket _sock;
160 };
161
162 class JChunkReader : public JReaderInterface
163 {
164 public:
165 #ifdef JALIB_ALLOCATOR
166 static void* operator new(size_t nbytes, void* p) { return p; }
167 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
168 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
169 #endif
170 JChunkReader ( JSocket sock, int chunkSize );
171 JChunkReader ( const JChunkReader& that );
172 ~JChunkReader();
173 JChunkReader& operator= ( const JChunkReader& that );
174 bool readOnce();
175 void readAll();
176 void reset();
177 bool ready() const { return _length == _read; }
178 const char* buffer() const{ return _buffer; }
179 bool hadError() const { return _hadError || !_sock.isValid(); }
180 int bytesRead() const {return _read;}
181 protected:
182 char* _buffer;
183 int _length;
184 int _read;
185 bool _hadError;
186 };
187
188 class JWriterInterface
189 {
190 public:
191 #ifdef JALIB_ALLOCATOR
192 static void* operator new(size_t nbytes, void* p) { return p; }
193 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
194 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
195 #endif
196 JWriterInterface ( JSocket& sock ) :_sock ( sock ) {}
197 virtual ~JWriterInterface() {}
198 virtual bool writeOnce() = 0;
199 virtual bool isDone() = 0;
200 virtual bool hadError() = 0;
201 const JSocket& socket() const{ return _sock; }
202 JSocket& socket() { return _sock; }
203 protected:
204 JSocket _sock;
205 };
206
207 class JChunkWriter : public JWriterInterface
208 {
209 public:
210 #ifdef JALIB_ALLOCATOR
211 static void* operator new(size_t nbytes, void* p) { return p; }
212 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
213 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
214 #endif
215 JChunkWriter ( JSocket sock, const char* buf, int len );
216 JChunkWriter ( const JChunkWriter& that );
217 ~JChunkWriter();
218 jalib::JChunkWriter& operator= ( const JChunkWriter& that );
219
220 bool isDone();
221 bool writeOnce();
222 bool hadError();
223
224 private:
225 char* _buffer;
226 int _length;
227 int _sent;
228 bool _hadError;
229 };
230
231
232 class JMultiSocketProgram
233 {
234 public:
235 #ifdef JALIB_ALLOCATOR
236 static void* operator new(size_t nbytes, void* p) { return p; }
237 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
238 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
239 #endif
240 virtual ~JMultiSocketProgram() {}
241 void addDataSocket ( JReaderInterface* sock );
242 void addListenSocket ( const JSocket& sock );
243 void monitorSockets ( double timeoutSec = -1 );
244 virtual void onData ( JReaderInterface* sock ) = 0;
245 virtual void onConnect ( const JSocket& sock, const struct sockaddr* remoteAddr,socklen_t remoteLen ) = 0;
246 virtual void onDisconnect ( JReaderInterface* sock ) {};
247 void setTimeoutInterval ( double dblTimeout );
248 virtual void onTimeoutInterval() {};
249 void addWrite ( JWriterInterface* write );
250 protected:
251 jalib::vector<JReaderInterface*> _dataSockets;
252 jalib::vector<JSocket> _listenSockets;
253 jalib::vector<JWriterInterface*> _writes;
254 private:
255 bool timeoutEnabled;
256 struct timeval timeoutInterval;
257 struct timeval stoptime;
258 };
259
260 } //namespace jalib
261
262 #endif