00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #if defined(WIN32)
00013 # include <errno.h>
00014 # include <ws2tcpip.h>
00015 #else
00016 # include <sys/errno.h>
00017 #endif
00018
00019 #include "assa/MemDump.h"
00020 #include "assa/IPv4Socket.h"
00021
00022 using namespace ASSA;
00023
00024 Streambuf*
00025 IPv4Socket::
00026 rdbuf (Streambuf* sb_)
00027 {
00028 trace_with_mask("IPv4Socket::rdbuf(sb_)",SOCKTRACE);
00029
00030 if (sb_ == 0 || sb_ == m_rdbuf) {
00031 return (sb_);
00032 }
00033 Streambuf* old = m_rdbuf;
00034 m_rdbuf = sb_;
00035 return (old);
00036 }
00037
00038
00039 bool
00040 IPv4Socket::
00041 open (const int domain_)
00042 {
00043 trace_with_mask("IPv4Socket::open",SOCKTRACE);
00044
00045 m_type = domain_;
00046
00047 m_fd = ::socket(domain_, SOCK_STREAM, 0);
00048
00049 if (!is_valid_handler (m_fd)) {
00050 EL((ASSAERR,"OS::socket() error: m_fd = %d\n", m_fd));
00051 setstate (Socket::failbit);
00052 disable_handler (m_fd);
00053 return (false);
00054 }
00055 DL ((SOCK,"domain = %d, m_fd = %d\n", domain_, m_fd));
00056
00057 clear ();
00058 turnOptionOn (Socket::nonblocking);
00059
00060 return (true);
00061 }
00062
00063 bool
00064 IPv4Socket::
00065 close()
00066 {
00067 trace_with_mask("IPv4Socket::close()",SOCKTRACE);
00068
00069 if (is_valid_handler (m_fd)) {
00070 DL((SOCK,"Closed FD: %d\n",m_fd));
00071
00072
00073 flush ();
00074 close_handler(m_fd);
00075 setstate (Socket::failbit);
00076
00077
00078
00079
00080
00081
00082
00083 if (m_rdbuf && m_rdbuf->in_avail ()) {
00084 for (int c; (c=m_rdbuf->sbumpc ()) != EOF;) { }
00085 }
00086 }
00087 return (true);
00088 }
00089
00090 bool
00091 IPv4Socket::
00092 connect (const Address& his_address_)
00093 {
00094 trace_with_mask("IPv4Socket::connect()",SOCKTRACE);
00095
00096 if (!is_valid_handler (m_fd) && open (getDomain()) == false) {
00097 return false;
00098 }
00099
00100 int ret = ::connect (m_fd,
00101 (SA*) his_address_.getAddress(),
00102 his_address_.getLength());
00103 if (ret < 0)
00104 {
00105 int e = get_errno ();
00106 if (e == EINPROGRESS || e == EWOULDBLOCK) {
00107 DL((SOCK,"FD: %d OS::connect() error\n",m_fd));
00108 }
00109 else {
00110 EL((SOCK,"FD: %d OS::connect() error\n",m_fd));
00111 }
00112 return (false);
00113 }
00114
00115 clear ();
00116
00117 DL((SOCK,"Connection opened on FD: %d\n", m_fd));
00118 return (true);
00119 }
00120
00121 bool
00122 IPv4Socket::
00123 bind (const Address& addr_)
00124 {
00125 trace_with_mask("IPv4Socket::bind",SOCKTRACE);
00126
00127 #if !defined(WIN32)
00128
00131 if ( getDomain() == AF_UNIX ) {
00132 char* p = ((SA_UN *) addr_.getAddress())->sun_path;
00133 m_path = new char[strlen(p)+1];
00134 strcpy(m_path, p);
00135 struct stat sb;
00136
00137 if (stat (m_path, &sb) == 0) {
00138 if ( S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode) ) {
00139 unlink(m_path);
00140 }
00141 }
00142 }
00143 #endif
00144
00145
00146
00147
00148
00149
00150 Assure_return ( turnOptionOn (reuseaddr) );
00151
00152 int rt = ::bind(m_fd, addr_.getAddress(), addr_.getLength());
00153
00154 if ( rt < 0) {
00155 EL((SOCK,"::bind() FD: %d failed\n",m_fd));
00156 setstate (Socket::failbit);
00157 return (false);
00158 }
00159 Assure_return ( (::listen(m_fd, 5) == 0) );
00160 return (true);
00161 }
00162
00174 IPv4Socket*
00175 IPv4Socket::
00176 accept ()
00177 {
00178 trace_with_mask("IPv4Socket::accept",SOCKTRACE);
00179
00180 socklen_t length = 0;
00181 SA* remote_address = NULL;
00182 handler_t new_fd;
00183
00184 disable_handler (new_fd);
00185
00186 if ( getDomain() == AF_UNIX ) {
00187 length = sizeof(struct sockaddr_in);
00188 remote_address = (SA*) new SA_IN;
00189 }
00190 else
00191 {
00192 remote_address = (SA*) new SA_UN;
00193 length = sizeof(struct sockaddr_un);
00194 }
00195 memset(remote_address, 0, length);
00196
00197 #if !defined (_CYGWIN32__)
00198 new_fd = ::accept(m_fd, remote_address, &length);
00199 #else
00200 new_fd = ::accept(m_fd, remote_address, (int*)&length);
00201 #endif
00202
00203 if (!is_valid_handler (new_fd)) {
00204 EL((ASSAERR,"::accept() failed (new_fd=%d)\n", new_fd));
00205 close();
00206 return NULL;
00207 }
00208 if (length == sizeof(SA_IN)) {
00209 SA_IN* sa_in = (SA_IN*) remote_address;
00210
00211 DL((SOCK,"Accepted new TCP connection from Addr %s, port %d\n",
00212 inet_ntoa(sa_in->sin_addr), ntohs( sa_in->sin_port)));
00213 }
00214 else {
00215 #if !defined(WIN32)
00216 SA_UN* sa_un = (SA_UN*) remote_address;
00217 DL((SOCK,"Accepted new UNIX connection from %s\n", sa_un->sun_path));
00218 #endif
00219 }
00220 delete remote_address;
00221
00222 IPv4Socket* s = new IPv4Socket (new_fd);
00223 s->clear ();
00224 s->turnOptionOn (Socket::nonblocking);
00225 return s;
00226 }
00227
00228 int
00229 IPv4Socket::
00230 read (char* packet_, const unsigned int size_)
00231 {
00232 trace_with_mask("IPv4Socket::read",SOCKTRACE);
00233
00234 register int len;
00235 register int sz = size_;
00236 char* tmp = packet_;
00237
00238 if (!is_valid_handler (m_fd) < 0) {
00239 return -1;
00240 }
00241
00242 len = 0;
00243 if (m_rdbuf->unbuffered ()) {
00244
00245
00246
00247
00248
00249
00250
00251
00252 if ((len = m_rdbuf->sbumpc ()) >= 0) {
00253 *tmp = len;
00254 len = 1;
00255 }
00256 }
00257 else {
00258 len = m_rdbuf->sgetn (tmp, sz);
00259 }
00260 if (len == -1)
00261 {
00264 if (get_errno () != EWOULDBLOCK) {
00265 EL((ASSAERR,"::read (fd=%d) failed.\n",m_fd));
00266 setstate (Socket::failbit);
00267 }
00268 return len;
00269 }
00270 tmp += len;
00271 sz -= len;
00272
00273 if ((size_ - sz) == 0)
00274 {
00275 DL((SOCK,"Peer has dropped connection FD: %d\n",m_fd));
00276 setstate (Socket::failbit | Socket::eofbit);
00277 return 0;
00278 }
00279
00280 DL((SOCKTRACE,"==> FD: %d Received %d bytes\n", m_fd, size_ - sz));
00281 MemDump::dump_to_log (SOCKTRACE, "Data received:", packet_, size_ - sz);
00282
00283
00284
00285
00286
00287
00288 return (size_ - sz);
00289 }
00290
00291 int
00292 IPv4Socket::
00293 write(const char* packet_, const unsigned int size_)
00294 {
00295 trace_with_mask("IPv4Socket::write()",SOCKTRACE);
00296
00297 int ret = 0;
00298
00299 if (!is_valid_handler (m_fd)) {
00300 return -1;
00301 }
00302
00303 if (m_rdbuf->unbuffered ())
00304 {
00305 int wlen = size_;
00306 char* p = (char*) packet_;
00307
00308 while (wlen-- > 0) {
00309 if (m_rdbuf->sputc (*p++) == EOF) {
00310 return (EOF);
00311 }
00312 }
00313 ret = p - packet_;
00314 }
00315 else {
00316 ret = m_rdbuf->sputn ((char*) packet_, size_);
00317 }
00318
00319 if (ret > 0) {
00320 DL((SOCK,"<= FD: %d Wrote %d bytes (requested %d bytes)\n",
00321 m_fd, ret, size_));
00322 MemDump::dump_to_log (SOCK, "Data written", (char*)packet_, ret);
00323 }
00324 return ret;
00325 }
00326
00327 IPv4Socket*
00328 IPv4Socket::
00329 clone () const
00330 {
00331 const char self[] = "IPv4Socket::clone";
00332 trace_with_mask(self,SOCKTRACE);
00333
00334 handler_t nfd = dup (m_fd);
00335 IPv4Socket* s = new IPv4Socket (nfd);
00336
00337 DL((SOCK,"Original socket has %d bytes in its get_area\n",
00338 m_rdbuf->in_avail ()));
00339
00340 if (!is_valid_handler (nfd) || !good ()) {
00341 s->setstate (Socket::failbit);
00342 }
00343 else {
00344 s->clear ();
00345 }
00346
00347 return s;
00348 }
00349
00350