IPSocket.h

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 /* INADDR_NONE */
00068 
00075 class IPSocket : public Logger, 
00076                  virtual public IOHandlerBase {
00077 private:
00078     IPSocket(const IPSocket&); 
00079     
00080 public:
00081     // Constructor / destructor
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_;        // default: on
00151         bool reuseport_;        // default: off
00152         bool tcp_nodelay_;      // default: off
00153         
00154         int recv_bufsize_;      // default: system setting
00155         int send_bufsize_;      // default: system setting
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     inline int logf(log_level_t level, const char *fmt, ...) PRINTFLIKE(3, 4);
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 } // namespace oasys
00297  
00298 #endif /* _OASYS_IP_SOCKET_H_ */

Generated on Fri Dec 22 14:47:59 2006 for DTN Reference Implementation by  doxygen 1.5.1