00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "tcpsocket.hh"
00024
00025 namespace Network
00026 {
00027
00028 void TcpSocket::connect(const std::string& hostname, int port)
00029 {
00030 _port = port;
00031 _socket = _bind(port, hostname);
00032 _connect(_socket, port, hostname);
00033 }
00034
00035 void TcpSocket::connect(int port)
00036 {
00037 _port = port;
00038 _socket = _bind(port);
00039 _listen(_socket);
00040 }
00041
00042 TcpSocket* TcpSocket::accept() const
00043 {
00044 TcpSocket* res;
00045
00046 #ifdef IPV6_ENABLED
00047 if (V4 == _version)
00048 #endif
00049 res = new TcpSocket(_accept(_port, _socket));
00050 #ifdef IPV6_ENABLED
00051 else
00052 res = new TcpSocket(_accept(_port, _socket), V6);
00053 #endif
00054 res->_port = _port;
00055 res->_proto_kind = _proto_kind;
00056 #ifdef TLS
00057 if (_tls)
00058 {
00059 res->_tls = true;
00060 res->_tls_main = false;
00061 res->_session = _session;
00062 res->_x509_cred = _x509_cred;
00063 res->enable_tls();
00064 }
00065 #endif
00066 return res;
00067 }
00068
00069 std::string TcpSocket::get_ip(TcpSocket *client) const
00070 {
00071 return _get_ip(_port, client->_socket);
00072 }
00073
00074 void TcpSocket::close()
00075 {
00076 if (_socket > 0)
00077 _close(_socket);
00078 _socket = 0;
00079 }
00080
00081 std::string TcpSocket::_read_line_bin(int socket, unsigned int psize)
00082 {
00083 char chr[MAXPKTSIZE];
00084 std::string str = "";
00085 int res = 1;
00086 unsigned int size = 0, read = 0;
00087 bool end = false;
00088
00089 if (socket < 0)
00090 throw NoConnection("No Socket", HERE);
00091 if (_buffer.size() >= 2 && !psize)
00092 {
00093 size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
00094 str = _buffer.substr(2, size);
00095 if (_buffer.size() > size + 2)
00096 _buffer = _buffer.substr(size + 2, _buffer.size() - size - 2);
00097 else
00098 _buffer = "";
00099 read = str.size();
00100 }
00101 if (psize && _buffer.size() >= psize)
00102 {
00103 str = _buffer.substr(0, psize);
00104 _buffer = _buffer.substr(psize, _buffer.size() - psize);
00105 return str;
00106 }
00107 else if (!psize)
00108 {
00109
00110 #ifdef TLS
00111 if (_tls)
00112 res = gnutls_record_recv(_session, chr, 2 - _buffer.size());
00113 else
00114 #endif
00115 res = recv(socket, chr, 2 - _buffer.size(), 0);
00116 if (res <= 1)
00117 throw ConnectionClosed("Connection Closed", HERE);
00118 if (_buffer.size())
00119 size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0];
00120 else
00121 size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1];
00122 _buffer = "";
00123 }
00124 else
00125 {
00126
00127
00128 str = _buffer;
00129 _buffer = "";
00130 size = psize;
00131 read = str.size();
00132 }
00133 while (!end)
00134 {
00135 memset(chr, 0, MAXPKTSIZE);
00136 #ifdef TLS
00137 if (_tls)
00138 res = gnutls_record_recv(_session, chr, size - read);
00139 else
00140 #endif
00141 res = recv(socket, chr, size - read, 0);
00142 if (res <= 0)
00143 throw ConnectionClosed("Connection Closed", HERE);
00144 str += std::string(chr, res).substr(0, res);
00145 read += res;
00146 if (read >= size)
00147 end = true;
00148 }
00149 return str;
00150 }
00151
00152 std::string TcpSocket::_read_line_bin(int socket, int& port,
00153 std::string& host,
00154 unsigned int psize)
00155 {
00156 char chr[MAXPKTSIZE];
00157 std::string str = "";
00158 int res = 1;
00159 struct sockaddr_in addr;
00160 #ifdef IPV6_ENABLED
00161 struct sockaddr_in6 addr6;
00162 #endif
00163 #ifdef LIBSOCKET_WIN
00164 int size;
00165 #else
00166 socklen_t size;
00167 #endif
00168 bool end = false;
00169 unsigned int pkg_size = 0, read = 0;
00170
00171 #ifdef IPV6_ENABLED
00172 if (V4 == _version)
00173 #endif
00174 size = sizeof(addr);
00175 #ifdef IPV6_ENABLED
00176 else
00177 size = sizeof(addr6);
00178 #endif
00179 if (socket < 0)
00180 throw NoConnection("No Socket", HERE);
00181 if (_buffer.size() >= 2 && !psize)
00182 {
00183 pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
00184 str = _buffer.substr(2, pkg_size);
00185 if (_buffer.size() > pkg_size + 2)
00186 _buffer = _buffer.substr(pkg_size + 2, _buffer.size() - pkg_size - 2);
00187 else
00188 _buffer = "";
00189 read = str.size();
00190 }
00191 if (psize && _buffer.size() >= psize)
00192 {
00193 str = _buffer.substr(0, psize);
00194 _buffer = _buffer.substr(psize, _buffer.size() - psize);
00195 return str;
00196 }
00197 else if (!psize)
00198 {
00199
00200 #ifdef TLS
00201 if (_tls)
00202 res = gnutls_record_recv(_session, chr, 2 - _buffer.size());
00203 else
00204 #endif
00205 res = recv(socket, chr, 2 - _buffer.size(), 0);
00206 if (res <= 1)
00207 throw ConnectionClosed("Connection Closed", HERE);
00208 if (_buffer.size())
00209 pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0];
00210 else
00211 pkg_size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1];
00212 _buffer = "";
00213 }
00214 else
00215 {
00216
00217
00218 str = _buffer;
00219 _buffer = "";
00220 pkg_size = psize;
00221 read = str.size();
00222 }
00223 while (!end)
00224 {
00225 #ifdef TLS
00226 if (_tls)
00227 res = gnutls_record_recv(_session, chr, size - read);
00228 else
00229 #endif
00230 res = recv(socket, chr, size - read, 0);
00231 #ifdef IPV6_ENABLED
00232 if (V4 == _version)
00233 #endif
00234 if (getpeername(socket, (struct sockaddr *) &addr, &size) < 0)
00235 throw GetpeernameError("getpeername error", HERE);
00236 #ifdef IPV6_ENABLED
00237 else
00238 if (getpeername(socket, (struct sockaddr *) &addr6, &size) < 0)
00239 throw GetpeernameError("getpeername error", HERE);
00240 #endif
00241 if (res <= 0)
00242 throw ConnectionClosed("Connection Closed", HERE);
00243 str += std::string(chr, res).substr(0, res);
00244 read += res;
00245 if (read >= pkg_size)
00246 end = true;
00247 }
00248 #ifdef IPV6_ENABLED
00249 if (V4 == _version)
00250 {
00251 #endif
00252 host = std::string(inet_ntoa(addr.sin_addr));
00253 port = ntohs(addr.sin_port);
00254 #ifdef IPV6_ENABLED
00255 }
00256 else
00257 {
00258 char buf[INET6_ADDRSTRLEN];
00259 if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0)
00260 throw InetntopError("Not a valid address", HERE);
00261 host = std::string(buf);
00262 port = ntohs(addr6.sin6_port);
00263 }
00264 #endif
00265 return str;
00266 }
00267 }