1 // ------------------------------------------------
6 // Windows version of ClientSocket. Handles the nitty gritty of actually
7 // reading and writing TCP
9 // (c) 2002 peercast.org
10 // ------------------------------------------------
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 // ------------------------------------------------
22 // TODO: fix socket closing
30 #include "..\common\stats.h"
32 #include "chkMemoryLeak.h"
33 #define DEBUG_NEW new(__FILE__, __LINE__)
38 // --------------------------------------------------
39 void WSAClientSocket::init()
41 WORD wVersionRequested;
45 wVersionRequested = MAKEWORD( 2, 0 );
46 err = WSAStartup( wVersionRequested, &wsaData );
48 throw SockException("Unable to init sockets");
50 //LOG4("WSAStartup: OK");
53 // --------------------------------------------------
54 bool ClientSocket::getHostname(char *str,size_t size,unsigned int ip) //JP-MOD
63 he = gethostbyaddr((char *)&ip,sizeof(ip),AF_INET);
67 LOG_DEBUG("getHostname: %d.%d.%d.%d -> %s", ((BYTE*)&ip)[0], ((BYTE*)&ip)[1], ((BYTE*)&ip)[2], ((BYTE*)&ip)[3], he->h_name);
68 strncpy(str,he->h_name,size-1);
75 unsigned int cache_ip = 0;
76 unsigned int cache_time = 0;
78 // --------------------------------------------------
79 unsigned int ClientSocket::getIP(char *name)
81 unsigned int ctime = sys->getTime();
82 bool null_flg = (name == NULL);
85 if ((cache_time != 0) && (cache_time + 60 > ctime)){
97 if (gethostname(szHostName, sizeof(szHostName))==0)
103 HOSTENT *he = WSAClientSocket::resolveHost(name);
109 LPSTR lpAddr = he->h_addr_list[0];
113 struct in_addr inAddr;
114 memmove (&inAddr, lpAddr, 4);
116 ret = inAddr.S_un.S_un_b.s_b1<<24 |
117 inAddr.S_un.S_un_b.s_b2<<16 |
118 inAddr.S_un.S_un_b.s_b3<<8 |
119 inAddr.S_un.S_un_b.s_b4;
129 // --------------------------------------------------
130 void WSAClientSocket::setLinger(int sec)
133 linger.l_onoff = (sec>0)?1:0;
134 linger.l_linger = sec;
136 if (setsockopt(sockNum, SOL_SOCKET, SO_LINGER, (const char *)&linger, sizeof (linger)) == -1)
137 throw SockException("Unable to set LINGER");
140 // --------------------------------------------------
141 void WSAClientSocket::setBlocking(bool yes)
143 unsigned long op = yes ? 0 : 1;
144 if (ioctlsocket(sockNum, FIONBIO, &op) == SOCKET_ERROR)
145 throw SockException("Can`t set blocking");
147 // --------------------------------------------------
148 void WSAClientSocket::setNagle(bool on)
150 int nodelay = (on==false);
151 if (setsockopt(sockNum, SOL_SOCKET, TCP_NODELAY, (char *)&nodelay, sizeof nodelay) == -1)
152 throw SockException("Unable to set NODELAY");
156 // --------------------------------------------------
157 void WSAClientSocket::setReuse(bool yes)
159 unsigned long op = yes ? 1 : 0;
160 if (setsockopt(sockNum,SOL_SOCKET,SO_REUSEADDR,(char *)&op,sizeof(unsigned long)) == -1)
161 throw SockException("Unable to set REUSE");
164 // --------------------------------------------------
165 void WSAClientSocket::setBufSize(int size)
169 int len = sizeof(op);
170 if (getsockopt(sockNum,SOL_SOCKET,SO_RCVBUF,(char *)&oldop,&len) == -1) {
171 LOG_DEBUG("Unable to get RCVBUF");
172 } else if (oldop < size) {
173 if (setsockopt(sockNum,SOL_SOCKET,SO_RCVBUF,(char *)&op,len) == -1)
174 LOG_DEBUG("Unable to set RCVBUF");
176 // LOG_DEBUG("*** recvbufsize:%d -> %d", oldop, op);
179 if (getsockopt(sockNum,SOL_SOCKET,SO_SNDBUF,(char *)&oldop,&len) == -1) {
180 LOG_DEBUG("Unable to get SNDBUF");
181 } else if (oldop < size) {
182 if (setsockopt(sockNum,SOL_SOCKET,SO_SNDBUF,(char *)&op,len) == -1)
183 LOG_DEBUG("Unable to set SNDBUF");
185 // LOG_DEBUG("*** sendbufsize: %d -> %d", oldop, op);
189 // --------------------------------------------------
190 HOSTENT *WSAClientSocket::resolveHost(const char *hostName)
194 if ((he = gethostbyname(hostName)) == NULL)
196 // if failed, try using gethostbyaddr instead
198 unsigned long ip = inet_addr(hostName);
200 if (ip == INADDR_NONE)
203 if ((he = gethostbyaddr((char *)&ip,sizeof(ip),AF_INET)) == NULL)
209 // --------------------------------------------------
210 void WSAClientSocket::open(Host &rh)
212 sockNum = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
214 if (sockNum == INVALID_SOCKET)
215 throw SockException("Can`t open socket");
225 memset(&remoteAddr,0,sizeof(remoteAddr));
227 remoteAddr.sin_family = AF_INET;
228 remoteAddr.sin_port = htons(host.port);
229 remoteAddr.sin_addr.S_un.S_addr = htonl(host.ip);
232 // --------------------------------------------------
233 void WSAClientSocket::checkTimeout(bool r, bool w)
235 int err = WSAGetLastError();
236 if (err == WSAEWOULDBLOCK)
246 FD_ZERO (&write_fds);
249 timeout.tv_sec = (int)this->writeTimeout/1000;
250 FD_SET (sockNum, &write_fds);
256 timeout.tv_sec = (int)this->readTimeout/1000;
257 FD_SET (sockNum, &read_fds);
267 int r=select (NULL, &read_fds, &write_fds, NULL, tp);
270 throw TimeoutException();
271 else if (r == SOCKET_ERROR)
272 throw SockException("select failed.");
276 sprintf(str,"%d",err);
277 throw SockException(str);
281 // --------------------------------------------------
282 void WSAClientSocket::checkTimeout2(bool r, bool w)
293 FD_ZERO (&write_fds);
296 timeout.tv_sec = (int)this->writeTimeout/1000;
297 FD_SET (sockNum, &write_fds);
303 timeout.tv_sec = (int)this->readTimeout/1000;
304 FD_SET (sockNum, &read_fds);
314 int r=select (NULL, &read_fds, &write_fds, NULL, tp);
317 throw TimeoutException();
318 else if (r == SOCKET_ERROR)
319 throw SockException("select failed.");
323 // --------------------------------------------------
324 Host WSAClientSocket::getLocalHost()
326 struct sockaddr_in localAddr;
328 int len = sizeof(localAddr);
329 if (getsockname(sockNum, (sockaddr *)&localAddr, &len) == 0)
330 return Host(SWAP4(localAddr.sin_addr.s_addr),0);
335 // --------------------------------------------------
336 void WSAClientSocket::connect()
338 if (::connect(sockNum,(struct sockaddr *)&remoteAddr,sizeof(remoteAddr)) == SOCKET_ERROR)
339 checkTimeout(false,true);
342 // --------------------------------------------------
343 int WSAClientSocket::read(void *p, int l)
349 if (rbDataSize >= l) {
350 memcpy(p, &apReadBuf[rbPos], l);
354 } else if (rbDataSize > 0) {
355 memcpy(p, &apReadBuf[rbPos], rbDataSize);
356 p = (char *) p + rbDataSize;
358 bytesRead += rbDataSize;
363 //int r = recv(sockNum, (char *)p, l, 0);
364 int r = recv(sockNum, apReadBuf, RBSIZE, 0);
365 if (r == SOCKET_ERROR)
367 // non-blocking sockets always fall through to here
368 checkTimeout(true,false);
372 throw EOFException("Closed on read");
376 stats.add(Stats::BYTESIN,r);
378 stats.add(Stats::LOCALBYTESIN,r);
389 // --------------------------------------------------
390 int WSAClientSocket::readUpto(void *p, int l)
395 int r = recv(sockNum, (char *)p, l, 0);
396 if (r == SOCKET_ERROR)
398 // non-blocking sockets always fall through to here
399 //checkTimeout(true,false);
407 stats.add(Stats::BYTESIN,r);
409 stats.add(Stats::LOCALBYTESIN,r);
415 if (bytesRead) break;
421 // --------------------------------------------------
422 void WSAClientSocket::write(const void *p, int l)
426 int r = send(sockNum, (char *)p, l, 0);
427 if (r == SOCKET_ERROR)
429 checkTimeout(false,true);
433 throw SockException("Closed on write");
438 stats.add(Stats::BYTESOUT,r);
440 stats.add(Stats::LOCALBYTESOUT,r);
449 // --------------------------------------------------
450 void WSAClientSocket::bufferingWrite(const void *p, int l)
452 if (bufList.isNull() && p != NULL){
454 int r = send(sockNum, (char *)p, l, 0);
455 if (r == SOCKET_ERROR){
456 int err = WSAGetLastError();
457 if (err == WSAEWOULDBLOCK){
459 // LOG_DEBUG("normal add");
463 sprintf(str,"%d",err);
464 throw SockException(str);
467 throw SockException("Closed on write");
469 stats.add(Stats::BYTESOUT,r);
471 stats.add(Stats::LOCALBYTESOUT,r);
479 // LOG_DEBUG("***************BufferingWrite");
487 tmp = bufList.getTop();
490 // LOG_DEBUG("tmp->pos = %d, tmp->len = %d, %d", tmp->pos, tmp->len, tmp);
491 while(tmp->pos < tmp->len){
492 int r = send(sockNum, (char*)(tmp->buf + tmp->pos), tmp->len - tmp->pos, 0);
493 // LOG_DEBUG("send = %d", r);
494 if (r == SOCKET_ERROR){
495 int err = WSAGetLastError();
496 if (err == WSAEWOULDBLOCK){
502 sprintf(str,"%d",err);
503 throw SockException(str);
507 throw SockException("Closed on write");
509 stats.add(Stats::BYTESOUT,r);
511 stats.add(Stats::LOCALBYTESOUT,r);
516 if (tmp->pos >= tmp->len){
517 // LOG_DEBUG("deleteTop");
527 // LOG_DEBUG("bufferingWrite end");
531 // --------------------------------------------------
532 void WSAClientSocket::checkBuffering(bool r, bool w)
534 int err = WSAGetLastError();
535 if (err == WSAEWOULDBLOCK)
545 FD_ZERO (&write_fds);
548 timeout.tv_sec = (int)this->writeTimeout/1000;
549 FD_SET (sockNum, &write_fds);
555 timeout.tv_sec = (int)this->readTimeout/1000;
556 FD_SET (sockNum, &read_fds);
566 int r=select (NULL, &read_fds, &write_fds, NULL, tp);
569 throw TimeoutException();
570 else if (r == SOCKET_ERROR)
571 throw SockException("select failed.");
575 sprintf(str,"%d",err);
576 throw SockException(str);
580 // --------------------------------------------------
581 void WSAClientSocket::bind(Host &h)
583 struct sockaddr_in localAddr;
585 if ((sockNum = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
586 throw SockException("Can`t open socket");
591 memset(&localAddr,0,sizeof(localAddr));
592 localAddr.sin_family = AF_INET;
593 localAddr.sin_port = htons(h.port);
594 localAddr.sin_addr.s_addr = INADDR_ANY;
596 if( ::bind (sockNum, (sockaddr *)&localAddr, sizeof(localAddr)) == -1)
597 throw SockException("Can`t bind socket");
599 if (::listen(sockNum,SOMAXCONN))
600 throw SockException("Can`t listen",WSAGetLastError());
604 // --------------------------------------------------
605 ClientSocket *WSAClientSocket::accept()
608 int fromSize = sizeof(sockaddr_in);
611 SOCKET conSock = ::accept(sockNum,(sockaddr *)&from,&fromSize);
614 if (conSock == INVALID_SOCKET)
618 WSAClientSocket *cs = new WSAClientSocket();
619 cs->sockNum = conSock;
621 cs->host.port = (from.sin_port & 0xff) << 8 | ((from.sin_port >> 8) & 0xff);
622 cs->host.ip = from.sin_addr.S_un.S_un_b.s_b1<<24 |
623 from.sin_addr.S_un.S_un_b.s_b2<<16 |
624 from.sin_addr.S_un.S_un_b.s_b3<<8 |
625 from.sin_addr.S_un.S_un_b.s_b4;
628 cs->setBlocking(false);
632 cs->setBufSize(65535);
637 // --------------------------------------------------
638 void WSAClientSocket::close()
643 shutdown(sockNum,SD_SEND); // fix from rev5
645 setReadTimeout(2000);
646 unsigned int stime = sys->getTime();
650 while (read(&c, sizeof(c)) > 0)
651 if (sys->getTime() - stime > 5)
653 }catch(StreamException &) {}
655 if (closesocket (sockNum))
656 LOG_ERROR("closesocket() error");
664 // --------------------------------------------------
665 bool WSAClientSocket::readReady()
667 if (rbDataSize) return true;
676 FD_SET (sockNum, &read_fds);
678 return select (sockNum+1, &read_fds, NULL, NULL, &timeout) == 1;