00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef _OASYS_IP_SOCKET_H_
00039 #define _OASYS_IP_SOCKET_H_
00040
00041 #include <stdlib.h>
00042 #include <sys/types.h>
00043 #include <sys/socket.h>
00044
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <errno.h>
00048
00049 #include "IO.h"
00050 #include "../compat/inttypes.h"
00051 #include "../debug/Log.h"
00052
00053 namespace oasys {
00054
00063 #define MAX_UDP_PACKET 65535
00064
00065 #ifndef INADDR_NONE
00066 #define INADDR_NONE 0
00067 #endif
00068
00075 class IPSocket : public Logger,
00076 virtual public IOHandlerBase {
00077 private:
00078 IPSocket(const IPSocket&);
00079
00080 public:
00081
00082 IPSocket(int socktype, const char* logbase);
00083 IPSocket(int socktype, int sock,
00084 in_addr_t remote_addr, u_int16_t remote_port,
00085 const char* logbase);
00086 virtual ~IPSocket();
00087
00089 void configure();
00090
00092
00093 virtual int bind(in_addr_t local_addr, u_int16_t local_port);
00094 virtual int connect();
00095 virtual int connect(in_addr_t remote_addr, u_int16_t remote_port);
00096 virtual int close();
00097 virtual int shutdown(int how);
00098
00099 virtual int send(const char* bp, size_t len, int flags);
00100 virtual int sendto(char* bp, size_t len, int flags,
00101 in_addr_t addr, u_int16_t port);
00102 virtual int sendmsg(const struct msghdr* msg, int flags);
00103
00104 virtual int recv(char* bp, size_t len, int flags);
00105 virtual int recvfrom(char* bp, size_t len, int flags,
00106 in_addr_t *addr, u_int16_t *port);
00107 virtual int recvmsg(struct msghdr* msg, int flags);
00108
00110
00114 int async_connect_result();
00115
00117 virtual int poll_sockfd(int events, int* revents, int timeout_ms);
00118
00120 enum state_t {
00121 INIT,
00122 LISTENING,
00123 CONNECTING,
00124 ESTABLISHED,
00125 RDCLOSED,
00126 WRCLOSED,
00127 CLOSED,
00128 FINI
00129 };
00130
00134 state_t state() { return state_; }
00135
00140 struct ip_socket_params {
00141 ip_socket_params() :
00142 reuseaddr_ (true),
00143 reuseport_ (false),
00144 tcp_nodelay_ (false),
00145 recv_bufsize_ (0),
00146 send_bufsize_ (0)
00147 {
00148 }
00149
00150 bool reuseaddr_;
00151 bool reuseport_;
00152 bool tcp_nodelay_;
00153
00154 int recv_bufsize_;
00155 int send_bufsize_;
00156 } params_;
00157
00159 inline int fd() { return fd_; }
00160
00162 inline in_addr_t local_addr();
00163
00165 inline u_int16_t local_port();
00166
00168 inline in_addr_t remote_addr();
00169
00171 inline u_int16_t remote_port();
00172
00174 inline void set_local_addr(in_addr_t addr);
00175
00177 inline void set_local_port(u_int16_t port);
00178
00180 inline void set_remote_addr(in_addr_t addr);
00181
00183 inline void set_remote_port(u_int16_t port);
00184
00185
00187
00188
00189
00192 void set_logfd(bool logfd) { logfd_ = logfd; }
00193
00195 void init_socket();
00196
00197 protected:
00198 int fd_;
00199 int socktype_;
00200 state_t state_;
00201 bool logfd_;
00202
00203 in_addr_t local_addr_;
00204 u_int16_t local_port_;
00205 in_addr_t remote_addr_;
00206 u_int16_t remote_port_;
00207
00208 void set_state(state_t state);
00209 const char* statetoa(state_t state);
00210
00211 inline void get_local();
00212 inline void get_remote();
00213
00214 };
00215
00216 in_addr_t
00217 IPSocket::local_addr()
00218 {
00219 if (local_addr_ == INADDR_NONE) get_local();
00220 return local_addr_;
00221 }
00222
00223 u_int16_t
00224 IPSocket::local_port()
00225 {
00226 if (local_port_ == 0) get_local();
00227 return local_port_;
00228 }
00229
00230 in_addr_t
00231 IPSocket::remote_addr()
00232 {
00233 if (remote_addr_ == INADDR_NONE) get_remote();
00234 return remote_addr_;
00235 }
00236
00237 u_int16_t
00238 IPSocket::remote_port()
00239 {
00240 if (remote_port_ == 0) get_remote();
00241 return remote_port_;
00242 }
00243
00244 void
00245 IPSocket::set_local_addr(in_addr_t addr)
00246 {
00247 local_addr_ = addr;
00248 }
00249
00250 void
00251 IPSocket::set_local_port(u_int16_t port)
00252 {
00253 local_port_ = port;
00254 }
00255
00256 void
00257 IPSocket::set_remote_addr(in_addr_t addr)
00258 {
00259 remote_addr_ = addr;
00260 }
00261
00262 void
00263 IPSocket::set_remote_port(u_int16_t port)
00264 {
00265 remote_port_ = port;
00266 }
00267
00268 void
00269 IPSocket::get_local()
00270 {
00271 if (fd_ < 0)
00272 return;
00273
00274 struct sockaddr_in sin;
00275 socklen_t slen = sizeof sin;
00276 if (::getsockname(fd_, (struct sockaddr *)&sin, &slen) == 0) {
00277 local_addr_ = sin.sin_addr.s_addr;
00278 local_port_ = ntohs(sin.sin_port);
00279 }
00280 }
00281
00282 void
00283 IPSocket::get_remote()
00284 {
00285 if (fd_ < 0)
00286 return;
00287
00288 struct sockaddr_in sin;
00289 socklen_t slen = sizeof sin;
00290 if (::getpeername(fd_, (struct sockaddr *)&sin, &slen) == 0) {
00291 remote_addr_ = sin.sin_addr.s_addr;
00292 remote_port_ = ntohs(sin.sin_port);
00293 }
00294 }
00295
00296 }
00297
00298 #endif