Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vsnet_socketudp.cpp
Go to the documentation of this file.
1 #include <config.h>
2 
3 #include "vsnet_headers.h"
4 
5 #include <list>
6 
7 #include "networking/const.h"
8 #include "vsnet_socketudp.h"
9 #include "vsnet_err.h"
10 #include "vsnet_debug.h"
11 #include "packet.h"
12 
13 using std::cout;
14 using std::cerr;
15 using std::endl;
16 using std::flush;
17 
18 /***********************************************************************
19 * VsnetUDPSocket - definition
20 ***********************************************************************/
21 
22 VsnetUDPSocket::VsnetUDPSocket( int sock, const AddressIP &remote_ip, SocketSet &socketset ) :
23  VsnetSocket( sock, remote_ip, "VsnetUDPSocket", socketset )
24  , _mtu_size_estimation( 1024 )
25 {
26  _negotiated_max_size = MAXBUFFER;
27  _recv_buf = new char[MAXBUFFER];
28 }
29 
31 {
32  delete[] _recv_buf;
33 }
34 
36 {
37  return _mtu_size_estimation;
38 }
39 
41 {
42  return 0;
43 }
44 
45 //int VsnetUDPSocket::sendbuf( PacketMem& packet, const AddressIP* to, int pcktflags )
46 //{
47 //COUT << "enter " << __PRETTY_FUNCTION__ << endl;
48 //int numsent;
49 //
51 //const sockaddr_in* dest = to;
52 //if( dest == NULL ) dest = &_remote_ip;
53 //
54 //assert( dest != NULL );
55 //
56 //if( (numsent = sendto( get_fd(), packet.getConstBuf(), packet.len(), 0, (sockaddr*) dest, sizeof(struct sockaddr_in)))<0)
57 //{
58 //COUT << "Error sending: " << vsnetLastError() << endl;
59 //return -1;
60 //}
61 //cout<<"Sent "<<numsent<<" bytes"<<" -> "<<inet_ntoa( dest->sin_addr)<<":"<<ntohs(dest->sin_port)<<endl;
62 //return numsent;
63 //}
65 {
66  _remote_ip = to;
67  return true;
68 }
69 int VsnetUDPSocket::sendbuf( Packet *packet, const AddressIP *to, int pcktflags )
70 {
71 //COUT << "enter " << __PRETTY_FUNCTION__ << endl;
72  int numsent;
73 
74  //In UDP mode, always send on this->sock
75  const sockaddr_in *dest = to;
76  if (dest == NULL) dest = &_remote_ip;
77  assert( dest != NULL );
78  if (packet->getSendBufferLength() >= 512) {
79  int *x = NULL;
80  COUT<<"Trying to send UDP "<<packet->getCommand()<<" of invalid size "
81  <<packet->getSendBufferLength()<<"(>=512)"<<endl;
82  packet->display( __FILE__, __LINE__ );
83  cout<<flush;
84  cerr<<flush;
85 #ifndef NO_CRASH_INVALID_UDP
86  (*x) = 1; //Cause crash.
87 #endif
88  return -1;
89  }
90  numsent = sendto( get_fd(),
91  packet->getSendBuffer(), packet->getSendBufferLength(),
92  0, (sockaddr*) dest, sizeof (struct sockaddr_in) );
93  if (numsent < 0) {
94  COUT<<"Error sending: "<<vsnetLastError()<<endl;
95  return -1;
96  }
97 //cout<<"Sent "<<numsent<<" bytes"<<" -> "<<inet_ntoa( dest->sin_addr)<<":"<<ntohs(dest->sin_port)<<endl;
98  return numsent;
99 }
100 
102 {
103  _cpq_mx.lock();
104  if ( _cpq.empty() ) {
105  _cpq_mx.unlock();
106  if (_set) _set->rem_pending( get_fd() );
107  return -1;
108  }
109  PacketMem buffer = _cpq.front().mem;
110  if (ipadr) *ipadr = _cpq.front().ip;
111  _cpq.pop();
112  _cpq_mx.unlock();
113  int len = buffer.len();
114  Packet packet( buffer );
115  *p = packet;
116  return len;
117 }
118 
119 void VsnetUDPSocket::dump( std::ostream &ostr ) const
120 {
121  ostr<<"( s="<<get_fd()<<" UDP r="<<_remote_ip<<" )";
122 }
123 
125 {
126  _cpq_mx.lock();
127  bool ret = (_cpq.empty() == false);
128  _cpq_mx.unlock();
129  return ret;
130 }
131 
133 {
134  int ret = 0;
135  socklen_t len1;
136  AddressIP from;
137  size_t lentoread = _negotiated_max_size;
138  if (datalen != -1)
139  lentoread = datalen;
140  //In UDP mode, always receive data on sock
141  len1 = sizeof (sockaddr_in);
142  ret = recvfrom( get_fd(), _recv_buf, lentoread,
143  0, (sockaddr*) (sockaddr_in*) &from, &len1 );
144  if (ret < 0) {
145  COUT<<" fd="<<get_fd()<<" error receiving: "
146  <<vsnetLastError()<<endl;
147  } else if (ret == 0) {
148  COUT<<" Received "<<ret<<" bytes : "<<_recv_buf
149  <<" (UDP socket closed, strange)"<<endl;
150  } else {
151 //COUT << "NETUI : Recvd " << ret << " bytes" << " <- " << from << endl;
152  Pending mem( _recv_buf, ret, from );
153  _cpq_mx.lock();
154  _cpq.push( mem );
155  _cpq_mx.unlock();
156  if (_set) _set->add_pending( get_fd() );
157  return true;
158  }
159  return false;
160 }
161