|
@@ -1,223 +1,234 @@
|
|
|
-#include <openssl/bio.h>
|
|
|
-#include <openssl/ssl.h>
|
|
|
+#define INCLUDE_SSL
|
|
|
#include "Klient.h"
|
|
|
+
|
|
|
#ifndef WIN32
|
|
|
-#include <string.h>
|
|
|
-#include <netdb.h>
|
|
|
-#include <sys/select.h>
|
|
|
+# include <netdb.h>
|
|
|
+# include <string.h>
|
|
|
+# include <sys/select.h>
|
|
|
#endif
|
|
|
+#include <Datei.h>
|
|
|
#include <Key.h>
|
|
|
-#include <Datei.h>
|
|
|
|
|
|
using namespace Network;
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
Klient::Klient()
|
|
|
- : ReferenceCounter()
|
|
|
+ : ReferenceCounter(),
|
|
|
+ errorOccured(0)
|
|
|
{
|
|
|
- memset(&server, 0, sizeof(server));
|
|
|
- server.sin_family = AF_INET;
|
|
|
- downStreamBytes = 0;
|
|
|
- upStreamBytes = 0;
|
|
|
- sock = 0;
|
|
|
- sendeKey = 0;
|
|
|
- empfangKey = 0;
|
|
|
+ memset(&server, 0, sizeof(server));
|
|
|
+ server.sin_family = AF_INET;
|
|
|
+ downStreamBytes = 0;
|
|
|
+ upStreamBytes = 0;
|
|
|
+ sock = 0;
|
|
|
+ sendeKey = 0;
|
|
|
+ empfangKey = 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
Klient::~Klient()
|
|
|
{
|
|
|
- if (sock)
|
|
|
- trenne();
|
|
|
- if (sendeKey)
|
|
|
- sendeKey->release();
|
|
|
- if (empfangKey)
|
|
|
- empfangKey->release();
|
|
|
+ if (sock) trenne();
|
|
|
+ if (sendeKey) sendeKey->release();
|
|
|
+ if (empfangKey) empfangKey->release();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
void Klient::setSendeKeyZ(Encryption::Key* key)
|
|
|
{
|
|
|
- if (sendeKey)
|
|
|
- sendeKey->release();
|
|
|
- sendeKey = key;
|
|
|
+ if (sendeKey) sendeKey->release();
|
|
|
+ sendeKey = key;
|
|
|
}
|
|
|
|
|
|
-void Klient::setEmpfangKeyZ(Encryption::Key* key)
|
|
|
+void Klient::setEmpfangKeyZ(
|
|
|
+ Encryption::Key* key)
|
|
|
{
|
|
|
- if (empfangKey)
|
|
|
- empfangKey->release();
|
|
|
- empfangKey = key;
|
|
|
+ if (empfangKey) empfangKey->release();
|
|
|
+ empfangKey = key;
|
|
|
}
|
|
|
|
|
|
void Klient::setSendeKey(const char* key, int len)
|
|
|
{
|
|
|
- if (!sendeKey)
|
|
|
- sendeKey = new Encryption::Key();
|
|
|
- sendeKey->setKey(key, len);
|
|
|
+ if (!sendeKey) sendeKey = new Encryption::Key();
|
|
|
+ sendeKey->setKey(key, len);
|
|
|
}
|
|
|
|
|
|
-void Klient::setEmpfangKey(const char* key, int len)
|
|
|
+void Klient::setEmpfangKey(
|
|
|
+ const char* key, int len)
|
|
|
{
|
|
|
- if (!empfangKey)
|
|
|
- empfangKey = new Encryption::Key();
|
|
|
- empfangKey->setKey(key, len);
|
|
|
+ if (!empfangKey) empfangKey = new Encryption::Key();
|
|
|
+ empfangKey->setKey(key, len);
|
|
|
}
|
|
|
|
|
|
-bool Klient::verbinde(unsigned short port, const char* ip)
|
|
|
+bool Klient::verbinde(
|
|
|
+ unsigned short port, const char* ip)
|
|
|
{
|
|
|
- if (sendeKey)
|
|
|
- sendeKey->setPos(0);
|
|
|
- if (empfangKey)
|
|
|
- empfangKey->setPos(0);
|
|
|
- if (sock)
|
|
|
- closesocket(sock);
|
|
|
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
- long sIp = inet_addr(ip);
|
|
|
- if (sIp == INADDR_NONE)
|
|
|
- {
|
|
|
- struct hostent* pHostInfo = gethostbyname(ip);
|
|
|
- if (pHostInfo == 0)
|
|
|
- return 0;
|
|
|
- sIp = *(long*)pHostInfo->h_addr_list[0];
|
|
|
- }
|
|
|
- memcpy((char*)&server.sin_addr, &sIp, sizeof(sIp));
|
|
|
- server.sin_port = htons(port);
|
|
|
- if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0)
|
|
|
- return 0;
|
|
|
- return 1;
|
|
|
+ if (sendeKey) sendeKey->setPos(0);
|
|
|
+ if (empfangKey) empfangKey->setPos(0);
|
|
|
+ if (sock) closesocket(sock);
|
|
|
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
+ long sIp = inet_addr(ip);
|
|
|
+ if (sIp == INADDR_NONE)
|
|
|
+ {
|
|
|
+ struct hostent* pHostInfo = gethostbyname(ip);
|
|
|
+ if (pHostInfo == 0) return 0;
|
|
|
+ sIp = *(long*)pHostInfo->h_addr_list[0];
|
|
|
+ }
|
|
|
+ memcpy((char*)&server.sin_addr, &sIp, sizeof(sIp));
|
|
|
+ server.sin_port = htons(port);
|
|
|
+ if (connect(sock, (struct sockaddr*)&server, sizeof(server))
|
|
|
+ < 0)
|
|
|
+ {
|
|
|
+ errorOccured = 1;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ errorOccured = 0;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
bool Klient::sende(const char* nachricht, int len)
|
|
|
{
|
|
|
- int ll = 0;
|
|
|
- while (len > 0)
|
|
|
- {
|
|
|
+ int ll = 0;
|
|
|
+ while (len > 0)
|
|
|
+ {
|
|
|
#ifdef WIN32
|
|
|
- int l = send(sock, nachricht + ll, len, 0);
|
|
|
+ int l = send(sock, nachricht + ll, len, 0);
|
|
|
#else
|
|
|
- int l = (int)send(sock, nachricht + ll, len, MSG_NOSIGNAL);
|
|
|
+ int l = (int)send(sock, nachricht + ll, len, MSG_NOSIGNAL);
|
|
|
#endif
|
|
|
- if (l <= 0)
|
|
|
- return 0;
|
|
|
- len -= l;
|
|
|
- ll += l;
|
|
|
- }
|
|
|
- upStreamBytes += ll;
|
|
|
- return 1;
|
|
|
+ if (l <= 0)
|
|
|
+ {
|
|
|
+ errorOccured = 1;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ len -= l;
|
|
|
+ ll += l;
|
|
|
+ }
|
|
|
+ upStreamBytes += ll;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
bool Klient::getNachricht(char* nachricht, int len)
|
|
|
{
|
|
|
- int ll = 0;
|
|
|
- while (len > 0)
|
|
|
- {
|
|
|
- int l = (int)recv(sock, nachricht + ll, len, MSG_WAITALL);
|
|
|
- if (l <= 0)
|
|
|
- return 0;
|
|
|
- len -= l;
|
|
|
- ll += l;
|
|
|
- }
|
|
|
- downStreamBytes += ll;
|
|
|
- return 1;
|
|
|
+ int ll = 0;
|
|
|
+ while (len > 0)
|
|
|
+ {
|
|
|
+ int l = (int)recv(sock, nachricht + ll, len, MSG_WAITALL);
|
|
|
+ if (l <= 0)
|
|
|
+ {
|
|
|
+ errorOccured = 1;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ len -= l;
|
|
|
+ ll += l;
|
|
|
+ }
|
|
|
+ downStreamBytes += ll;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
bool Klient::sendeEncrypted(const char* nachricht, int len)
|
|
|
{
|
|
|
- if (!sendeKey)
|
|
|
- return sende(nachricht, len);
|
|
|
- Encryption::Bytes* n = new Encryption::Bytes(nachricht, len);
|
|
|
- sendeKey->codieren(dynamic_cast<Framework::Encryption::Bytes*>(n->getThis()));
|
|
|
- int ll = 0;
|
|
|
- while (len > 0)
|
|
|
- {
|
|
|
+ if (!sendeKey) return sende(nachricht, len);
|
|
|
+ Encryption::Bytes* n = new Encryption::Bytes(nachricht, len);
|
|
|
+ sendeKey->codieren(
|
|
|
+ dynamic_cast<Framework::Encryption::Bytes*>(n->getThis()));
|
|
|
+ int ll = 0;
|
|
|
+ while (len > 0)
|
|
|
+ {
|
|
|
#ifdef WIN32
|
|
|
- int l = send(sock, n->getBytes() + ll, len, 0);
|
|
|
+ int l = send(sock, n->getBytes() + ll, len, 0);
|
|
|
#else
|
|
|
- int l = (int)send(sock, n->getBytes() + ll, len, MSG_NOSIGNAL);
|
|
|
+ int l = (int)send(sock, n->getBytes() + ll, len, MSG_NOSIGNAL);
|
|
|
#endif
|
|
|
- if (l <= 0)
|
|
|
- {
|
|
|
- n->release();
|
|
|
- return 0;
|
|
|
- }
|
|
|
- len -= l;
|
|
|
- ll += l;
|
|
|
- }
|
|
|
- upStreamBytes += ll;
|
|
|
- n->release();
|
|
|
- return 1;
|
|
|
+ if (l <= 0)
|
|
|
+ {
|
|
|
+ n->release();
|
|
|
+ errorOccured = 1;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ len -= l;
|
|
|
+ ll += l;
|
|
|
+ }
|
|
|
+ upStreamBytes += ll;
|
|
|
+ n->release();
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
-bool Klient::getNachrichtEncrypted(char* nachricht, int len)
|
|
|
+bool Klient::getNachrichtEncrypted(
|
|
|
+ char* nachricht, int len)
|
|
|
{
|
|
|
- if (!empfangKey)
|
|
|
- return getNachricht(nachricht, len);
|
|
|
- int ll = 0;
|
|
|
- while (len > 0)
|
|
|
- {
|
|
|
- int l = (int)recv(sock, nachricht + ll, len, MSG_WAITALL);
|
|
|
- if (l <= 0)
|
|
|
- return 0;
|
|
|
- len -= l;
|
|
|
- ll += l;
|
|
|
- }
|
|
|
- Encryption::Bytes* n = new Encryption::Bytes();
|
|
|
- n->setBytesZ(nachricht, ll);
|
|
|
- empfangKey->decodieren(n);
|
|
|
- downStreamBytes += ll;
|
|
|
- return 1;
|
|
|
+ if (!empfangKey) return getNachricht(nachricht, len);
|
|
|
+ int ll = 0;
|
|
|
+ while (len > 0)
|
|
|
+ {
|
|
|
+ int l = (int)recv(sock, nachricht + ll, len, MSG_WAITALL);
|
|
|
+ if (l <= 0)
|
|
|
+ {
|
|
|
+ errorOccured = 1;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ len -= l;
|
|
|
+ ll += l;
|
|
|
+ }
|
|
|
+ Encryption::Bytes* n = new Encryption::Bytes();
|
|
|
+ n->setBytesZ(nachricht, ll);
|
|
|
+ empfangKey->decodieren(n);
|
|
|
+ downStreamBytes += ll;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
-int Klient::getDownloadBytes(bool reset)
|
|
|
+int Klient::getDownloadBytes(
|
|
|
+ bool reset)
|
|
|
{
|
|
|
- int ret = downStreamBytes;
|
|
|
- if (reset)
|
|
|
- downStreamBytes = 0;
|
|
|
- return ret;
|
|
|
+ int ret = downStreamBytes;
|
|
|
+ if (reset) downStreamBytes = 0;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
-int Klient::getUploadBytes(bool reset)
|
|
|
+int Klient::getUploadBytes(
|
|
|
+ bool reset)
|
|
|
{
|
|
|
- int ret = upStreamBytes;
|
|
|
- if (reset)
|
|
|
- upStreamBytes = 0;
|
|
|
- return ret;
|
|
|
+ int ret = upStreamBytes;
|
|
|
+ if (reset) upStreamBytes = 0;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
bool Klient::trenne()
|
|
|
{
|
|
|
- if (!sock)
|
|
|
- return 1;
|
|
|
- if (sendeKey)
|
|
|
- sendeKey->setPos(0);
|
|
|
- if (empfangKey)
|
|
|
- empfangKey->setPos(0);
|
|
|
- if (closesocket(sock) < 0)
|
|
|
- return 0;
|
|
|
- sock = 0;
|
|
|
- return 1;
|
|
|
+ if (!sock) return 1;
|
|
|
+ if (sendeKey) sendeKey->setPos(0);
|
|
|
+ if (empfangKey) empfangKey->setPos(0);
|
|
|
+ if (closesocket(sock) < 0)
|
|
|
+ {
|
|
|
+ errorOccured = 1;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ sock = 0;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
|
|
|
bool Klient::hatNachricht(int zeit)
|
|
|
{
|
|
|
- fd_set set;
|
|
|
- FD_ZERO(&set);
|
|
|
- FD_SET(sock, &set);
|
|
|
- timeval time = { zeit / 1000, zeit };
|
|
|
- return select(0, &set, 0, 0, &time) == 1;
|
|
|
+ fd_set set;
|
|
|
+ FD_ZERO(&set);
|
|
|
+ FD_SET(sock, &set);
|
|
|
+ timeval time = {zeit / 1000, zeit};
|
|
|
+ int result = select(0, &set, 0, 0, &time) == 1;
|
|
|
+ if (result < 0)
|
|
|
+ errorOccured = 1;
|
|
|
+ return result > 0;
|
|
|
}
|
|
|
|
|
|
unsigned short Klient::getServerPort() const
|
|
|
{
|
|
|
- return htons(server.sin_port);
|
|
|
+ return htons(server.sin_port);
|
|
|
}
|
|
|
|
|
|
const char* Klient::getServerIp() const
|
|
|
{
|
|
|
- return inet_ntoa(server.sin_addr);
|
|
|
+ return inet_ntoa(server.sin_addr);
|
|
|
}
|
|
|
|
|
|
bool Klient::waitForNextMessage() const
|
|
@@ -235,132 +246,132 @@ bool Klient::waitForNextMessage() const
|
|
|
if (rv == -1) return 0;
|
|
|
}
|
|
|
if (!sock) return 0;
|
|
|
- char c;
|
|
|
- int l = (int)recv(sock, &c, 1, MSG_WAITALL | MSG_PEEK);
|
|
|
- if (l <= 0)
|
|
|
- return 0;
|
|
|
- return 1;
|
|
|
+ char c;
|
|
|
+ int l = (int)recv(sock, &c, 1, MSG_WAITALL | MSG_PEEK);
|
|
|
+ if (l <= 0) return 0;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
+bool Klient::isConnected()
|
|
|
+ const
|
|
|
+{
|
|
|
+ return sock != 0 && !errorOccured;
|
|
|
+}
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
SSLKlient::SSLKlient()
|
|
|
- : ReferenceCounter()
|
|
|
+ : ReferenceCounter()
|
|
|
{
|
|
|
- ctx = SSL_CTX_new(TLS_client_method());
|
|
|
- SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
|
|
|
- SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
|
|
|
- ip = 0;
|
|
|
- port = 0;
|
|
|
- bio = BIO_new_ssl_connect(ctx);
|
|
|
- BIO_get_ssl(bio, &ssl);
|
|
|
- downStreamBytes = 0;
|
|
|
- upStreamBytes = 0;
|
|
|
- connected = 0;
|
|
|
+ ctx = SSL_CTX_new(TLS_client_method());
|
|
|
+ SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
|
|
|
+ SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
|
|
|
+ ip = 0;
|
|
|
+ port = 0;
|
|
|
+ bio = BIO_new_ssl_connect(ctx);
|
|
|
+ BIO_get_ssl(bio, &ssl);
|
|
|
+ downStreamBytes = 0;
|
|
|
+ upStreamBytes = 0;
|
|
|
+ connected = 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
SSLKlient::~SSLKlient()
|
|
|
{
|
|
|
- if (this->ip)
|
|
|
- this->ip->release();
|
|
|
- if (connected)
|
|
|
- trenne();
|
|
|
- BIO_free_all(bio);
|
|
|
- SSL_CTX_free(ctx);
|
|
|
+ if (this->ip) this->ip->release();
|
|
|
+ if (connected) trenne();
|
|
|
+ BIO_free_all(bio);
|
|
|
+ SSL_CTX_free(ctx);
|
|
|
#ifdef WIN32
|
|
|
- OPENSSL_thread_stop();
|
|
|
+ OPENSSL_thread_stop();
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-bool SSLKlient::verbinde(unsigned short port, const char* ip)
|
|
|
+bool SSLKlient::verbinde(
|
|
|
+ unsigned short port, const char* ip)
|
|
|
{
|
|
|
- this->port = port;
|
|
|
- if (this->ip)
|
|
|
- this->ip->release();
|
|
|
- this->ip = new Text(ip);
|
|
|
- Text adr = ip;
|
|
|
- adr += ":";
|
|
|
- adr += port;
|
|
|
- BIO_set_conn_hostname(bio, (const char*)adr);
|
|
|
- connected = BIO_do_connect(bio) > 0;
|
|
|
- if (connected && BIO_do_handshake(bio) <= 0)
|
|
|
- trenne();
|
|
|
- return connected;
|
|
|
+ this->port = port;
|
|
|
+ if (this->ip) this->ip->release();
|
|
|
+ this->ip = new Text(ip);
|
|
|
+ Text adr = ip;
|
|
|
+ adr += ":";
|
|
|
+ adr += port;
|
|
|
+ BIO_set_conn_hostname(bio, (const char*)adr);
|
|
|
+ connected = BIO_do_connect(bio) > 0;
|
|
|
+ if (connected && BIO_do_handshake(bio) <= 0) trenne();
|
|
|
+ return connected;
|
|
|
}
|
|
|
|
|
|
bool SSLKlient::sende(const char* nachricht, int len)
|
|
|
{
|
|
|
- int ll = 0;
|
|
|
- while (len > 0)
|
|
|
- {
|
|
|
- int l = SSL_write(ssl, nachricht + ll, len);
|
|
|
- if (l <= 0)
|
|
|
- return 0;
|
|
|
- len -= l;
|
|
|
- ll += l;
|
|
|
- }
|
|
|
- upStreamBytes += ll;
|
|
|
- return 1;
|
|
|
+ int ll = 0;
|
|
|
+ while (len > 0)
|
|
|
+ {
|
|
|
+ int l = SSL_write(ssl, nachricht + ll, len);
|
|
|
+ if (l <= 0) return 0;
|
|
|
+ len -= l;
|
|
|
+ ll += l;
|
|
|
+ }
|
|
|
+ upStreamBytes += ll;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
bool SSLKlient::getNachricht(char* nachricht, int len)
|
|
|
{
|
|
|
- if (!connected)
|
|
|
- return 0;
|
|
|
- int ll = 0;
|
|
|
- while (len > 0)
|
|
|
- {
|
|
|
- int l = SSL_read(ssl, nachricht + ll, len);
|
|
|
- if (l <= 0)
|
|
|
- return 0;
|
|
|
- len -= l;
|
|
|
- ll += l;
|
|
|
- }
|
|
|
- downStreamBytes += ll;
|
|
|
- return 1;
|
|
|
+ if (!connected) return 0;
|
|
|
+ int ll = 0;
|
|
|
+ while (len > 0)
|
|
|
+ {
|
|
|
+ int l = SSL_read(ssl, nachricht + ll, len);
|
|
|
+ if (l <= 0) return 0;
|
|
|
+ len -= l;
|
|
|
+ ll += l;
|
|
|
+ }
|
|
|
+ downStreamBytes += ll;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
-int SSLKlient::getDownloadBytes(bool reset)
|
|
|
+int SSLKlient::getDownloadBytes(
|
|
|
+ bool reset)
|
|
|
{
|
|
|
- int ret = downStreamBytes;
|
|
|
- if (reset)
|
|
|
- downStreamBytes = 0;
|
|
|
- return ret;
|
|
|
+ int ret = downStreamBytes;
|
|
|
+ if (reset) downStreamBytes = 0;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
-int SSLKlient::getUploadBytes(bool reset)
|
|
|
+int SSLKlient::getUploadBytes(
|
|
|
+ bool reset)
|
|
|
{
|
|
|
- int ret = upStreamBytes;
|
|
|
- if (reset)
|
|
|
- upStreamBytes = 0;
|
|
|
- return ret;
|
|
|
+ int ret = upStreamBytes;
|
|
|
+ if (reset) upStreamBytes = 0;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
bool SSLKlient::trenne()
|
|
|
{
|
|
|
- BIO_ssl_shutdown(bio);
|
|
|
- connected = 0;
|
|
|
- return 1;
|
|
|
+ BIO_ssl_shutdown(bio);
|
|
|
+ connected = 0;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-bool SSLKlient::hatNachricht(int zeit)
|
|
|
+
|
|
|
+bool SSLKlient::hatNachricht(
|
|
|
+ int zeit)
|
|
|
{
|
|
|
- fd_set set;
|
|
|
- FD_ZERO(&set);
|
|
|
- FD_SET(SSL_get_rfd(ssl), &set);
|
|
|
- timeval time = { zeit / 1000, zeit };
|
|
|
- return SSL_pending(ssl) > 0 || select(0, &set, 0, 0, &time) == 1;
|
|
|
+ fd_set set;
|
|
|
+ FD_ZERO(&set);
|
|
|
+ FD_SET(SSL_get_rfd(ssl), &set);
|
|
|
+ timeval time = {zeit / 1000, zeit};
|
|
|
+ return SSL_pending(ssl) > 0 || select(0, &set, 0, 0, &time) == 1;
|
|
|
}
|
|
|
|
|
|
-unsigned short SSLKlient::getServerPort() const
|
|
|
+unsigned short
|
|
|
+SSLKlient::getServerPort() const
|
|
|
{
|
|
|
- return port;
|
|
|
+ return port;
|
|
|
}
|
|
|
|
|
|
const char* SSLKlient::getServerIp() const
|
|
|
{
|
|
|
- return ip->getText();
|
|
|
+ return ip->getText();
|
|
|
}
|