sock.cpp File Reference


Detailed Description

Provides low-level IP socket communication.

Definition in file sock.cpp.

#include <vector>
#include <list>
#include <string>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "sock.h"
#include "params.h"

Include dependency graph for sock.cpp:

Go to the source code of this file.

Classes

struct  s_data
 Stores data to send/receive later. More...
struct  s_receive_later
 Stores data to receive later. More...
struct  s_send_later
 Stores data to send later. More...

Functions

void sock_async (s_socket &socket)
 Sets asynchronous mode for the socket.
void sock_cancel_caching (s_socket &socket)
 Cancels caching.
void sock_create_later (s_socket &socket, bool using_window)
 Creates cache entries.
void sock_erase_later (s_socket &socket)
 Frees cache data (receives and sends), without send / receive.
void sock_flush_later (s_socket &socket)
 Flushes cache data (receives and sends).
int sock_get_address_type (string host)
 Discovers type of address.
time_t sock_get_last_io (s_socket &socket, char mode)
 Returns last read/receive or send timestamp on socket.
size_t sock_get_receive_size (s_socket &socket)
 Get size of input buffer on socket.
size_t sock_lo_get_input_amount (s_socket &socket, char *buff, size_t len)
 Low-level: receives data from the socket input queue, but leaves it in it (can be used for check how mush data is waiting).
size_t sock_lo_recv (s_socket &socket, char *buff, size_t len)
 Low-level read from socket (Windows(TM) only).
size_t sock_lo_send (s_socket &socket, char *buff, size_t len)
 Low-level send to socket (Windows(TM) only).
size_t sock_read (s_socket &socket, char *data, size_t size, int &error_code, bool &connection_closed)
 Reads data from connected socket.
unsigned int sock_send (s_socket &socket, const char *data, unsigned int size, int &error_code)
 Writes data to connected socket.
void sock_send_cache ()
 Sends and receive all pending data (in the cache), should be called in loop.
void sock_unread (s_socket &socket, char *data, size_t size)
 Puts buffer back to queue as if it weren't read.

Variables

vector< s_receive_laterreceive_later
 Packets to receive later.
vector< s_send_latersend_later
 Packets to send later.


Function Documentation

void sock_async s_socket socket  ) 
 

Sets asynchronous mode for the socket.

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
socket Socket handle

Definition at line 696 of file sock.cpp.

References s_socket::handle, and sock_set_blocking().

Referenced by dcc_loop(), identd_check(), and sock_connect().

00697 {
00698 #ifdef _WIN32
00699 #   ifndef __GNUC__
00700     HWND WindowHandle=AllocateHWnd(WndProc);
00701 #   else
00702     HWND WindowHandle=AllocateHWnd((void*)WndProc);
00703 #   endif
00704     socket.wnd=WindowHandle;
00705     WSAAsyncSelect(socket.handle,WindowHandle,WM_TCPASYNCSELECT,FD_READ | FD_CLOSE);
00706 #else
00707     sock_set_blocking(socket,true);
00708 #endif
00709 }

Here is the call graph for this function:

void sock_cancel_caching s_socket socket  ) 
 

Cancels caching.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
socket Socket handle

Definition at line 852 of file sock.cpp.

References s_socket::handle, sock_erase_later(), and sock_flush_later().

Referenced by dcc_loop().

00853 {
00854     sock_flush_later(socket);
00855     sock_erase_later(socket);
00856 #ifdef _WIN32
00857     WSAAsyncSelect(socket.handle,socket.wnd,0,0);
00858 #endif
00859 }

Here is the call graph for this function:

void sock_create_later s_socket socket,
bool  using_window
 

Creates cache entries.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
socket Socket handle to create cache for
using_window Are we using window message callback to receive? (Windows(TM) only)

Definition at line 668 of file sock.cpp.

References s_receive_later::has_error, s_receive_later::last_error, s_receive_later::last_recv, s_send_later::last_send, receive_later, send_later, s_receive_later::socket, s_send_later::socket, and s_receive_later::using_window.

Referenced by sock_accept(), sock_accept6(), and sock_connect().

00669 {
00670 #ifndef _WIN32
00671     using_window=false;
00672 #endif
00673     s_receive_later r;
00674     r.has_error=false;
00675     r.socket=socket;
00676     r.using_window=using_window;
00677     r.last_error=0;
00678     r.last_recv=time(NULL);
00679     receive_later.push_back(r);
00680 
00681     s_send_later s;
00682     //s.has_error=false;
00683     s.socket=socket;
00684     //s.last_error=0;
00685     s.last_send=time(NULL);
00686     send_later.push_back(s);
00687 }

void sock_erase_later s_socket socket  ) 
 

Frees cache data (receives and sends), without send / receive.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
socket Socket handle to free cache for

Definition at line 805 of file sock.cpp.

References s_socket::handle, s_socket::last_io, receive_later, and send_later.

Referenced by sock_cancel_caching(), sock_close(), and sock_connect().

00806 {
00807     vector<s_send_later>::iterator i1;
00808     for(i1=send_later.begin(); i1!=send_later.end(); i1++) {
00809         if((*i1).socket.handle==socket.handle) {
00810             list<s_data>::iterator ii;
00811 again_1:
00812             for(ii=(*i1).data.begin(); ii!=(*i1).data.end(); ii++) {
00813                 if(!(*ii).closed)
00814                     delete[] (*ii).data;
00815                 (*i1).data.erase(ii);
00816                 goto again_1;
00817             }
00818             send_later.erase(i1);
00819             break;
00820         }
00821     }
00822     vector<s_receive_later>::iterator i2;
00823     for(i2=receive_later.begin(); i2!=receive_later.end(); i2++) {
00824         if((*i2).socket.handle==socket.handle) {
00825             if((*i2).socket.last_io<socket.last_io)
00826                 (*i2).socket.last_io=socket.last_io;
00827             else
00828                 socket.last_io=(*i2).socket.last_io;
00829 
00830             list<s_data>::iterator ii;
00831 again_2:
00832             for(ii=(*i2).data.begin(); ii!=(*i2).data.end(); ii++) {
00833                 if(!(*ii).closed)
00834                     delete[] (*ii).data;
00835                 (*i1).data.erase(ii);
00836                 goto again_2;
00837             }
00838 
00839             receive_later.erase(i2);
00840             break;
00841         }
00842     }
00843 }

void sock_flush_later s_socket socket  ) 
 

Flushes cache data (receives and sends).

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
socket Socket handle to flush cache for

Definition at line 718 of file sock.cpp.

References s_socket::handle, s_socket::last_io, receive_later, send_later, sock_lo_send(), SOCKET_ERROR, WSAEWOULDBLOCK, and WSAGetLastError.

Referenced by dcc_broadcast(), dcc_flush_all(), dcc_loop(), irc_disconnect(), irc_quit(), main(), sock_cancel_caching(), and sock_close().

00719 {
00720     vector<s_send_later>::iterator i1;
00721     for(i1=send_later.begin(); i1!=send_later.end(); i1++) {
00722         if((*i1).socket.handle==socket.handle) {
00723             if((*i1).socket.last_io<socket.last_io)
00724                 (*i1).socket.last_io=socket.last_io;
00725             else
00726                 socket.last_io=(*i1).socket.last_io;
00727 
00728             (*i1).last_send=time(NULL);
00729 
00730             list<s_data>::iterator i2;
00731         again:
00732             for(i2=(*i1).data.begin(); i2!=(*i1).data.end(); i2++) {
00733                 if(!(*i2).closed /*&& !(*i2).error*/) {
00734                     size_t l=1024;
00735                     if((*i2).len<l)
00736                         l=(*i2).len;
00737                     size_t Sent=sock_lo_send((*i1).socket,(*i2).data,l);
00738                     if(Sent==SOCKET_ERROR) {
00739                         int la=WSAGetLastError();
00740                         if(la!=WSAEWOULDBLOCK) {
00741                             vector<s_receive_later>::iterator i3;
00742                             for(i3=receive_later.begin(); i3!=receive_later.end(); i3++)
00743                                 if((*i3).socket.handle==(*i1).socket.handle) {
00744                                     (*i3).has_error=true;
00745                                     if((*i3).last_error==0)
00746                                         (*i3).last_error=la;
00747                                     break;
00748                                 }
00749                             //(*i1).has_error=true;
00750                             (*i1).data.pop_front();
00751                             goto again;
00752                         } else {
00753                             break;
00754                         }
00755                     }
00756                     if(Sent>0)
00757                         (*i1).socket.last_io=time(NULL);
00758                     if(Sent<(*i2).len) {
00759                         char* buf=new char[(*i2).len-Sent];
00760                         memcpy(buf,&(*i2).data[Sent],(*i2).len-Sent);
00761                         delete[] (*i2).data;
00762                         (*i2).len-=Sent;
00763                         (*i2).data=buf;
00764                     } else {
00765                         delete[] (*i2).data;
00766                         (*i1).data.pop_front();
00767                     }
00768                     goto again;
00769                 }
00770 
00771                 (*i1).data.pop_front();
00772                 goto again;
00773             }
00774             break;
00775         }
00776     }
00777     vector<s_receive_later>::iterator i2;
00778     for(i2=receive_later.begin(); i2!=receive_later.end(); i2++) {
00779         if((*i2).socket.handle==socket.handle) {
00780             if((*i2).socket.last_io<socket.last_io)
00781                 (*i2).socket.last_io=socket.last_io;
00782             else
00783                 socket.last_io=(*i2).socket.last_io;
00784 
00785             list<s_data>::iterator i3;
00786         again2:
00787             for(i3=(*i2).data.begin(); i3!=(*i2).data.end(); i3++) {
00788                 if(!(*i3).closed /*&& !(*i3).error*/)
00789                     delete[] (*i3).data;
00790                 (*i2).data.pop_front();
00791                 goto again2;
00792             }
00793             break;
00794         }
00795     }
00796 }

Here is the call graph for this function:

int sock_get_address_type string  host  ) 
 

Discovers type of address.

Author:
VooDooMan
Version:
1
Date:
2005
Parameters:
host IP of host name
Return values:
0 Given host is DNS name of host
4 Given host is numeric IPv4 address
6 Given host is numeric IPv6 address

Definition at line 930 of file sock.cpp.

Referenced by dcc_send_file(), and sock_resolve().

00931 {
00932     unsigned int i1, i2, i3, i4;
00933     int x=sscanf(host.c_str(),"%u.%u.%u.%u", &i1, &i2, &i3, &i4);
00934     if(x==4)
00935         return 4;
00936     if(host.find(":",0)!=string::npos)
00937         return 6;
00938     return 0;
00939 }

time_t sock_get_last_io s_socket socket,
char  mode
 

Returns last read/receive or send timestamp on socket.

Author:
VooDooMan
Version:
1
Date:
2005
Parameters:
socket Socket handle
mode Set to 'r' to get timestamp of last receive; set to 's' to get time of last send; set to 'a' (default) (stands for "all") to get most recent timestamp on both send and receive
Returns:
Timestamp of last send or receive on socket
Warning:
If argument "mode" contain neither 'r', nor 's', nor 'a', the returned value is zero

Definition at line 871 of file sock.cpp.

References s_socket::handle, s_socket::last_io, receive_later, and send_later.

Referenced by dcc_loop().

00872 {
00873     time_t last_io=0;
00874 
00875     if(mode=='r') {
00876         vector<s_receive_later>::iterator i2;
00877         for(i2=receive_later.begin(); i2!=receive_later.end(); i2++)
00878             if((*i2).socket.handle==socket.handle) {
00879                 last_io=(*i2).last_recv;
00880                 break;
00881             }
00882     }
00883 
00884     if(mode=='s') {
00885         vector<s_send_later>::iterator i2;
00886         for(i2=send_later.begin(); i2!=send_later.end(); i2++)
00887             if((*i2).socket.handle==socket.handle) {
00888                 last_io=(*i2).last_send;
00889                 break;
00890             }
00891     }
00892 
00893     if(mode=='a') {
00894         last_io=socket.last_io;
00895 
00896         vector<s_receive_later>::iterator i2;
00897         for(i2=receive_later.begin(); i2!=receive_later.end(); i2++)
00898             if((*i2).socket.handle==socket.handle) {
00899                 if(last_io<(*i2).socket.last_io)
00900                     last_io=(*i2).socket.last_io;
00901                 if(last_io<(*i2).last_recv)
00902                     last_io=(*i2).last_recv;
00903                 break;
00904             }
00905 
00906         vector<s_send_later>::iterator i1;
00907         for(i1=send_later.begin(); i1!=send_later.end(); i1++)
00908             if((*i1).socket.handle==socket.handle) {
00909                 if(last_io<(*i1).socket.last_io)
00910                     last_io=(*i1).socket.last_io;
00911                 if(last_io<(*i1).last_send)
00912                     last_io=(*i1).last_send;
00913                 break;
00914             }
00915     }
00916 
00917     return last_io;
00918 }

size_t sock_get_receive_size s_socket socket  ) 
 

Get size of input buffer on socket.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
socket Socket handle
Returns:
Number of bytes waiting to receive

Definition at line 459 of file sock.cpp.

References s_socket::handle, s_socket::last_io, and receive_later.

Referenced by dcc_loop().

00460 {
00461     size_t result=0;
00462 
00463     vector<s_receive_later>::iterator i1;
00464     for(i1=receive_later.begin(); i1!=receive_later.end(); i1++) {
00465         if((*i1).socket.handle==socket.handle) {
00466             if((*i1).socket.last_io<socket.last_io)
00467                 (*i1).socket.last_io=socket.last_io;
00468             else
00469                 socket.last_io=(*i1).socket.last_io;
00470 
00471             list<s_data>::iterator i2;
00472             for(i2=(*i1).data.begin(); i2!=(*i1).data.end(); i2++) {
00473                 if(!(*i2).closed /*&& !(*i2).error*/)
00474                     result+=(*i2).len;
00475             }
00476             break;
00477         }
00478     }
00479     return result;
00480 }

size_t sock_lo_get_input_amount s_socket socket,
char *  buff,
size_t  len
 

Low-level: receives data from the socket input queue, but leaves it in it (can be used for check how mush data is waiting).

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
socket Socket handle
buff Buffer to receive
len Length of the buffer
Returns:
Returns number of bytes waiting in queue

Definition at line 835 of file win_sock.cpp.

References s_socket::handle.

Referenced by sock_send_cache().

00836 {
00837     //return recv(socket.handle,buff,len,MSG_PEEK);
00838     return recvfrom(socket.handle,buff,(int)len,MSG_PEEK,NULL,NULL);
00839 }

size_t sock_lo_recv s_socket socket,
char *  buff,
size_t  len
 

Low-level read from socket (Windows(TM) only).

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
socket Socket handle
buff Buffer to store received data
len Maximum length of the buffer
Returns:
Returns number of bytes actually received

Definition at line 851 of file win_sock.cpp.

References s_socket::handle, s_socket::last_io, and s_socket::received.

Referenced by sock_send_cache().

00852 {
00853     //size_t received=recv(socket.handle,buff,len,0);
00854     size_t received=recvfrom(socket.handle,buff,(int)len,0,NULL,NULL);
00855     if(received>0) {
00856         socket.last_io=time(NULL);
00857         socket.received+=received;
00858     }
00859     return received;
00860 }

size_t sock_lo_send s_socket socket,
char *  buff,
size_t  len
 

Low-level send to socket (Windows(TM) only).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
socket Socket handle
buff Buffer to send
len Length of the buffer
Returns:
Returns number of bytes actually sent
Parameters:
socket  Cleans-up the structure

Definition at line 815 of file win_sock.cpp.

References s_socket::handle, s_socket::last_io, and s_socket::sent.

Referenced by sock_flush_later(), and sock_send_cache().

00816 {
00817     size_t sent=send(socket.handle,buff,(int)len,0);
00818     if(sent>0) {
00819         socket.last_io=time(NULL);
00820         socket.sent+=sent;
00821     }
00822     return sent;
00823 }

size_t sock_read s_socket socket,
char *  data,
size_t  size,
int &  error_code,
bool &  connection_closed
 

Reads data from connected socket.

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
socket Socket handle of connected socket
data Buffer to be filled up to "size" bytes
size Size of buffer (maximum bytes to be read)
error_code Returns OS's socket error
connection_closed Returns true if data was successfuly read, but remote host closed the connection (this is not error and read of data is working correctly)
Returns:
Returns amount of read data in bytes

Definition at line 354 of file sock.cpp.

References s_socket::handle, s_socket::last_io, and receive_later.

Referenced by botnet_loop(), botnet_receive(), dcc_loop(), identd_check(), and irc_loop_putserv().

00355 {
00356     error_code=0;
00357     connection_closed=false;
00358     {
00359         vector<s_receive_later>::iterator i1;
00360         for(i1=receive_later.begin(); i1!=receive_later.end(); i1++) {
00361             if((*i1).socket.handle==socket.handle) {
00362                 if((*i1).socket.last_io<socket.last_io)
00363                     (*i1).socket.last_io=socket.last_io;
00364                 else
00365                     socket.last_io=(*i1).socket.last_io;
00366 
00367                 if((*i1).data.begin()==(*i1).data.end() && (*i1).last_error) {
00368                     error_code=(*i1).last_error;
00369                     return 0;
00370                 }
00371 
00372                 list<s_data>::iterator i2;
00373                 connection_closed=false;
00374 again:
00375                 for(i2=(*i1).data.begin(); i2!=(*i1).data.end(); i2++) {
00376                     (*i1).last_recv=time(NULL);
00377 
00378                     error_code=0;
00379                     if((*i2).closed) {
00380                         connection_closed=true;
00381                         (*i1).data.pop_front();
00382                         goto again;
00383                     }
00384                     connection_closed=false;
00385                     /*error_code=(*i2).error;
00386                     if(error_code || connection_closed)
00387                         return 0;*/
00388 
00389                     size_t l=size;
00390                     if((*i2).len<=l) {
00391                         l=(*i2).len;
00392                         if((*i2).len)
00393                             memcpy(data,(*i2).data,l);
00394                         delete[] (*i2).data;
00395                         (*i1).data.pop_front();
00396                         error_code=0;
00397                         return l;
00398                     }
00399                     if((*i2).len>l) {
00400                         memcpy(data,(*i2).data,l);
00401                         char* buf=new char[(*i2).len-l];
00402                         memcpy(buf,&((*i2).data[l]),(*i2).len-l);
00403                         delete[] (*i2).data;
00404                         (*i2).len-=l;
00405                         (*i2).data=buf;
00406                         error_code=0;
00407                         return l;
00408                     }
00409                 }
00410                 error_code=0;
00411                 //connection_closed=false;
00412                 return 0;
00413             }
00414         }
00415     }
00416 
00417     return 0;
00418 }

unsigned int sock_send s_socket socket,
const char *  data,
unsigned int  size,
int &  error_code
 

Writes data to connected socket.

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
socket Socket handle of connected socket
data Buffer to write
size Size of buffer
error_code Returns OS's socket error
Returns:
Returns amount of sent data in bytes

Definition at line 299 of file sock.cpp.

References s_data::closed, s_data::data, s_socket::handle, s_socket::last_io, s_send_later::last_send, s_data::len, send_later, and s_send_later::socket.

Referenced by botnet_loop(), botnet_send_command(), botnet_send_control(), dcc_loop(), dcc_partyline_message(), dcc_send_msg(), identd_check(), and irc_putserv_immediately().

00300 {
00301     {
00302         {
00303             {
00304             again:
00305                 bool got=false;
00306                 vector<s_send_later>::iterator i1;
00307                 for(i1=send_later.begin(); i1!=send_later.end(); i1++) {
00308                     if((*i1).socket.handle==socket.handle) {
00309                         if((*i1).socket.last_io<socket.last_io)
00310                             (*i1).socket.last_io=socket.last_io;
00311                         else
00312                             socket.last_io=(*i1).socket.last_io;
00313                         (*i1).last_send=time(NULL);
00314                         got=true;
00315                         break;
00316                     }
00317                 }
00318                 if(!got) {
00319                     s_send_later s;
00320                     //s.has_error=false;
00321                     s.socket=socket;
00322                     //s.last_error=0;
00323                     s.last_send=time(NULL);
00324                     send_later.push_back(s);
00325                     goto again;
00326                 }
00327                 s_data d;
00328                 d.closed=false;
00329                 //d.error=0;
00330                 d.len=size;
00331                 d.data=new char[size];
00332                 memcpy(d.data,data,size);
00333                 (*i1).data.push_back(d);
00334 
00335                 error_code=0;
00336                 return size;
00337             }
00338         }
00339     }
00340 }

void sock_send_cache  ) 
 

Sends and receive all pending data (in the cache), should be called in loop.

Author:
VooDooMan
Version:
2
Date:
2005

Definition at line 488 of file sock.cpp.

References s_data::closed, s_data::data, s_data::len, receive_later, send_later, sock_lo_get_input_amount(), sock_lo_recv(), sock_lo_send(), SOCKET_ERROR, WSAEWOULDBLOCK, and WSAGetLastError.

00489 {
00490     unsigned int _tmp_size_=1024*64;
00491     char* _tmp_=new char[_tmp_size_];
00492 
00493     vector<s_receive_later>::iterator i2;
00494     for(i2=receive_later.begin(); i2!=receive_later.end(); i2++) {
00495         {
00496             {
00497                 // do a dummy operation
00498                 size_t res=sock_lo_get_input_amount((*i2).socket,_tmp_,_tmp_size_);
00499 
00500                 int error_code=WSAGetLastError();
00501                 if(res!=SOCKET_ERROR)
00502                     error_code=0;
00503                 if(error_code && error_code!=WSAEWOULDBLOCK) {
00504                     if(!(*i2).has_error) {
00505                         (*i2).has_error=true;
00506                         (*i2).last_error=error_code;
00507                     }
00508                 }
00509             }
00510         }
00511 
00512         if((*i2).using_window)
00513             continue;
00514         char tmp[1024];
00515         socklen_t tmp2=1024;
00516         getsockopt((*i2).socket.handle,SOL_SOCKET,SO_ERROR,tmp,&tmp2);
00517 
00518         for(;;) {
00519             {
00520                 // do a dummy operation
00521                 size_t res=sock_lo_get_input_amount((*i2).socket,_tmp_,_tmp_size_);
00522 
00523                 int error_code=WSAGetLastError();
00524                 if(res!=SOCKET_ERROR)
00525                     error_code=0;
00526                 if(error_code && error_code!=WSAEWOULDBLOCK) {
00527                     if(!(*i2).has_error) {
00528                         (*i2).has_error=true;
00529                         (*i2).last_error=error_code;
00530                     }
00531                 }
00532             }
00533 
00534             fd_set a;
00535             timeval t;
00536 
00537             t.tv_sec=0;
00538             t.tv_usec=1;
00539 
00540             FD_ZERO(&a);
00541             FD_SET((*i2).socket.handle,&a);
00542 
00543             int i=select((int)(*i2).socket.handle+1,&a,NULL,NULL,&t);
00544             if(i==0)
00545                 break;
00546 
00547             unsigned int max_size=1024*64;
00548             char* buf=new char[max_size];
00549             //max_size=sock_lo_get_input_amount((*i2).socket,buf,max_size);
00550             size_t size_=sock_lo_recv((*i2).socket,buf,max_size);
00551             if(size_==SOCKET_ERROR) {
00552                 delete[] buf;
00553                 int error_code=WSAGetLastError();
00554                 if(error_code==WSAEWOULDBLOCK)
00555                     break;
00556                 if(!(*i2).has_error) {
00557                     (*i2).has_error=true;
00558                     (*i2).last_error=error_code;
00559                     break;
00560                 }
00561                 break;
00562             }
00563             if(size_>0) {
00564                 (*i2).socket.last_io=time(NULL);
00565                 /*
00566                 vector<s_send_later>::iterator i1;
00567                 i1=send_later.begin();
00568                 if(i1!=send_later.end()) {
00569                     (*i1).socket.last_io=time(NULL);
00570                     (*i1).last_send=time(NULL);
00571                 }
00572                 */
00573                 (*i2).socket.last_io=time(NULL);
00574                 (*i2).last_recv=time(NULL);
00575             }
00576             if(size_==0) {
00577                 delete[] buf;
00578                 if(!(*i2).has_error) {
00579                     s_data d;
00580                     d.closed=true;
00581                     //d.error=0;
00582                     (*i2).data.push_back(d);
00583                     (*i2).has_error=true;
00584                 }
00585                 break;
00586             }
00587             if(size_) {
00588                 s_data d;
00589                 d.closed=false;
00590                 //d.error=0;
00591                 d.len=size_;
00592                 d.data=buf;
00593                 (*i2).data.push_back(d);
00594             }
00595         }
00596     }
00597 
00598     vector<s_send_later>::iterator i1;
00599     for(i1=send_later.begin(); i1!=send_later.end(); i1++) {
00600     again:
00601         list<s_data>::iterator i2;
00602         try {
00603             i2=(*i1).data.begin();
00604         } catch(...) {
00605             continue;
00606         }
00607         for(i2=(*i1).data.begin(); i2!=(*i1).data.end(); i2++) {
00608             size_t l=1024;
00609             if((*i2).len<l)
00610                 l=(*i2).len;
00611             size_t Sent=sock_lo_send((*i1).socket,(*i2).data,l);
00612             if(Sent==SOCKET_ERROR) {
00613                 int la=WSAGetLastError();
00614                 if(la==WSAEWOULDBLOCK)
00615                     break;
00616                 /*if(!(*i1).has_error)*/ {
00617                     vector<s_receive_later>::iterator i2;
00618                     for(i2=receive_later.begin(); i2!=receive_later.end(); i2++)
00619                         if((*i2).socket.handle==(*i1).socket.handle) {
00620                             (*i2).has_error=true;
00621                             if((*i2).last_error==0)
00622                                 (*i2).last_error=la;
00623                             break;
00624                         }
00625                     /*s_data d;
00626                     d.closed=false;
00627                     d.error=la;
00628                     (*i1).data.push_back(d);
00629                     (*i1).has_error=true;*/
00630                 }
00631                 break;
00632             }
00633             if(Sent>0) {
00634                 (*i1).socket.last_io=time(NULL);
00635                 /*
00636                 vector<s_receive_later>::iterator i2;
00637                 i2=receive_later.begin();
00638                 if(i2!=receive_later.end())
00639                     (*i2).socket.last_io=time(NULL);
00640                 */
00641                 (*i1).socket.last_io=time(NULL);
00642                 (*i1).last_send=time(NULL);
00643             }
00644             if(Sent<(*i2).len) {
00645                 char* buf=new char[(*i2).len-Sent];
00646                 memcpy(buf,&(*i2).data[Sent],(*i2).len-Sent);
00647                 delete[] (*i2).data;
00648                 (*i2).len-=Sent;
00649                 (*i2).data=buf;
00650             } else {
00651                 delete[] (*i2).data;
00652                 (*i1).data.pop_front();
00653             }
00654             goto again;
00655         }
00656     }
00657     delete[] _tmp_;
00658 }

Here is the call graph for this function:

void sock_unread s_socket socket,
char *  data,
size_t  size
 

Puts buffer back to queue as if it weren't read.

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
socket Socket handle of connected socket
data Buffer to be filled up to "size" bytes
size Size of buffer (maximum bytes to be read)

Definition at line 429 of file sock.cpp.

References s_data::closed, s_data::data, s_socket::handle, s_socket::last_io, s_data::len, and receive_later.

00430 {
00431     {
00432         vector<s_receive_later>::iterator i1;
00433         for(i1=receive_later.begin(); i1!=receive_later.end(); i1++) {
00434             if((*i1).socket.handle==socket.handle) {
00435                 if((*i1).socket.last_io<socket.last_io)
00436                     (*i1).socket.last_io=socket.last_io;
00437                 else
00438                     socket.last_io=(*i1).socket.last_io;
00439                 s_data d;
00440                 d.closed=false;
00441                 //d.error=0;
00442                 d.data=data;
00443                 d.len=size;
00444                 (*i1).data.push_front(d);
00445                 return;
00446             }
00447         }
00448     }
00449 }


Variable Documentation

vector<s_receive_later> receive_later
 

Packets to receive later.

Definition at line 147 of file sock.cpp.

Referenced by sock_create_later(), sock_erase_later(), sock_flush_later(), sock_get_last_io(), sock_get_receive_size(), sock_read(), sock_send_cache(), and sock_unread().

vector<s_send_later> send_later
 

Packets to send later.

Definition at line 146 of file sock.cpp.

Referenced by sock_create_later(), sock_erase_later(), sock_flush_later(), sock_get_last_io(), sock_send(), and sock_send_cache().


Generated on Sun Jul 10 05:37:32 2005 for VooDoo cIRCle by doxygen 1.4.3

Hosted by SourceForge.net Logo