00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _OASYS_IP_SOCKET_H_
00018 #define _OASYS_IP_SOCKET_H_
00019
00020 #include <stdlib.h>
00021 #include <sys/types.h>
00022 #include <sys/socket.h>
00023
00024 #include <netinet/in.h>
00025 #include <arpa/inet.h>
00026 #include <errno.h>
00027
00028 #include "IO.h"
00029 #include "../compat/inttypes.h"
00030 #include "../debug/Log.h"
00031
00032 namespace oasys {
00033
00042 #define MAX_UDP_PACKET 65535
00043
00044 #ifndef INADDR_NONE
00045 #define INADDR_NONE 0
00046 #endif
00047
00054 class IPSocket : public Logger,
00055 virtual public IOHandlerBase {
00056 private:
00057 IPSocket(const IPSocket&);
00058
00059 public:
00060
00061 IPSocket(int socktype, const char* logbase);
00062 IPSocket(int socktype, int sock,
00063 in_addr_t remote_addr, u_int16_t remote_port,
00064 const char* logbase);
00065 virtual ~IPSocket();
00066
00068 void configure();
00069
00071
00072 virtual int bind(in_addr_t local_addr, u_int16_t local_port);
00073 virtual int connect();
00074 virtual int connect(in_addr_t remote_addr, u_int16_t remote_port);
00075 virtual int close();
00076 virtual int shutdown(int how);
00077
00078 virtual int send(const char* bp, size_t len, int flags);
00079 virtual int sendto(char* bp, size_t len, int flags,
00080 in_addr_t addr, u_int16_t port);
00081 virtual int sendmsg(const struct msghdr* msg, int flags);
00082
00083 virtual int recv(char* bp, size_t len, int flags);
00084 virtual int recvfrom(char* bp, size_t len, int flags,
00085 in_addr_t *addr, u_int16_t *port);
00086 virtual int recvmsg(struct msghdr* msg, int flags);
00087
00089
00093 int async_connect_result();
00094
00096 virtual int poll_sockfd(int events, int* revents, int timeout_ms);
00097
00099 enum state_t {
00100 INIT,
00101 LISTENING,
00102 CONNECTING,
00103 ESTABLISHED,
00104 RDCLOSED,
00105 WRCLOSED,
00106 CLOSED,
00107 FINI
00108 };
00109
00113 state_t state() { return state_; }
00114
00119 struct ip_socket_params {
00120 ip_socket_params() :
00121 reuseaddr_ (true),
00122 reuseport_ (false),
00123 tcp_nodelay_ (false),
00124 broadcast_ (false),
00125 multicast_ (false),
00126 mcast_ttl_ (1),
00127 recv_bufsize_ (0),
00128 send_bufsize_ (0)
00129 {
00130 }
00131
00132 bool reuseaddr_;
00133 bool reuseport_;
00134 bool tcp_nodelay_;
00135 bool broadcast_;
00136 bool multicast_;
00137
00138 u_int mcast_ttl_;
00139
00140 int recv_bufsize_;
00141 int send_bufsize_;
00142 } params_;
00143
00145 inline int fd() { return fd_; }
00146
00148 inline in_addr_t local_addr();
00149
00151 inline u_int16_t local_port();
00152
00154 inline in_addr_t remote_addr();
00155
00157 inline u_int16_t remote_port();
00158
00160 inline void set_local_addr(in_addr_t addr);
00161
00163 inline void set_local_port(u_int16_t port);
00164
00166 inline void set_remote_addr(in_addr_t addr);
00167
00169 inline void set_remote_port(u_int16_t port);
00170
00171
00173
00174
00175
00178 void set_logfd(bool logfd) { logfd_ = logfd; }
00179
00181 void init_socket();
00182
00183 protected:
00184 int fd_;
00185 int socktype_;
00186 state_t state_;
00187 bool logfd_;
00188
00189 in_addr_t local_addr_;
00190 u_int16_t local_port_;
00191 in_addr_t remote_addr_;
00192 u_int16_t remote_port_;
00193
00194 void set_state(state_t state);
00195 const char* statetoa(state_t state);
00196
00197 inline void get_local();
00198 inline void get_remote();
00199
00200 };
00201
00202 in_addr_t
00203 IPSocket::local_addr()
00204 {
00205 if (local_addr_ == INADDR_NONE) get_local();
00206 return local_addr_;
00207 }
00208
00209 u_int16_t
00210 IPSocket::local_port()
00211 {
00212 if (local_port_ == 0) get_local();
00213 return local_port_;
00214 }
00215
00216 in_addr_t
00217 IPSocket::remote_addr()
00218 {
00219 if (remote_addr_ == INADDR_NONE) get_remote();
00220 return remote_addr_;
00221 }
00222
00223 u_int16_t
00224 IPSocket::remote_port()
00225 {
00226 if (remote_port_ == 0) get_remote();
00227 return remote_port_;
00228 }
00229
00230 void
00231 IPSocket::set_local_addr(in_addr_t addr)
00232 {
00233 local_addr_ = addr;
00234 }
00235
00236 void
00237 IPSocket::set_local_port(u_int16_t port)
00238 {
00239 local_port_ = port;
00240 }
00241
00242 void
00243 IPSocket::set_remote_addr(in_addr_t addr)
00244 {
00245 remote_addr_ = addr;
00246 }
00247
00248 void
00249 IPSocket::set_remote_port(u_int16_t port)
00250 {
00251 remote_port_ = port;
00252 }
00253
00254 void
00255 IPSocket::get_local()
00256 {
00257 if (fd_ < 0)
00258 return;
00259
00260 struct sockaddr_in sin;
00261 socklen_t slen = sizeof sin;
00262 if (::getsockname(fd_, (struct sockaddr *)&sin, &slen) == 0) {
00263 local_addr_ = sin.sin_addr.s_addr;
00264 local_port_ = ntohs(sin.sin_port);
00265 }
00266 }
00267
00268 void
00269 IPSocket::get_remote()
00270 {
00271 if (fd_ < 0)
00272 return;
00273
00274 struct sockaddr_in sin;
00275 socklen_t slen = sizeof sin;
00276 if (::getpeername(fd_, (struct sockaddr *)&sin, &slen) == 0) {
00277 remote_addr_ = sin.sin_addr.s_addr;
00278 remote_port_ = ntohs(sin.sin_port);
00279 }
00280 }
00281
00282 }
00283
00284 #endif