summaryrefslogtreecommitdiff
path: root/vdr-vdrmanager/sock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vdr-vdrmanager/sock.cpp')
-rw-r--r--vdr-vdrmanager/sock.cpp220
1 files changed, 108 insertions, 112 deletions
diff --git a/vdr-vdrmanager/sock.cpp b/vdr-vdrmanager/sock.cpp
index e2d4d36..a860b53 100644
--- a/vdr-vdrmanager/sock.cpp
+++ b/vdr-vdrmanager/sock.cpp
@@ -3,10 +3,9 @@
*/
#include <unistd.h>
#include <vdr/plugin.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
#include "sock.h"
#include "helpers.h"
+#include "compressor.h"
static int clientno = 0;
@@ -15,9 +14,6 @@ static int clientno = 0;
*/
cVdrmanagerSocket::cVdrmanagerSocket() {
sock = -1;
- useSSL = false;
- password = "";
- forceCheckSvdrp = false;
}
cVdrmanagerSocket::~cVdrmanagerSocket() {
@@ -55,36 +51,21 @@ const char * cVdrmanagerSocket::GetPassword() {
return password;
}
-void cVdrmanagerSocket::LogSSLError() {
-
- char * error = ERR_error_string(ERR_get_error(), NULL);
-
- esyslog("SSL error: %s", error);
-
-}
-
/*
* cVdrmonServerSocket
*/
-cVdrmanagerServerSocket::cVdrmanagerServerSocket() : cVdrmanagerSocket() {
-
- sslContext = NULL;
+cVdrmanagerServerSocket::cVdrmanagerServerSocket() :
+ cVdrmanagerSocket() {
}
cVdrmanagerServerSocket::~cVdrmanagerServerSocket() {
}
-bool cVdrmanagerServerSocket::Create(int port, const char * password, bool forceCheckSvrp,
- bool useSSL, const char * pemFile) {
+bool cVdrmanagerServerSocket::Create(int port, const char * password, bool forceCheckSvrp, int compressionMode) {
- this->password = password;
+ this->password = password;
this->forceCheckSvdrp = forceCheckSvrp;
- this->useSSL = useSSL;
-
- // create SSL context
- if (useSSL && !InitSSL(pemFile)) {
- return false;
- }
+ this->compressionMode = compressionMode;
// create socket
sock = socket(PF_INET, SOCK_STREAM, 0);
@@ -133,18 +114,12 @@ cVdrmanagerClientSocket * cVdrmanagerServerSocket::Accept() {
int newsock = accept(sock, (struct sockaddr *) &clientname, &size);
if (newsock > 0) {
// create client socket
- newsocket = new cVdrmanagerClientSocket(password);
+ newsocket = new cVdrmanagerClientSocket(password, compressionMode);
if (!newsocket->Attach(newsock)) {
delete newsocket;
return NULL;
}
- // Attach client SSL
- if (!newsocket->InitSSL(sslContext)) {
- delete newsocket;
- return NULL;
- }
-
if (!IsPasswordSet() || forceCheckSvdrp == true) {
bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr);
if (!accepted) {
@@ -155,51 +130,34 @@ cVdrmanagerClientSocket * cVdrmanagerServerSocket::Accept() {
}
dsyslog(
"[vdrmanager] connect from %s, port %hd - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED");
-
}
- } else if (errno != EINTR && errno != EAGAIN) {
+ } else if (errno != EINTR && errno != EAGAIN
+ )
LOG_ERROR;
- }
return newsocket;
}
-bool cVdrmanagerServerSocket::InitSSL(const char * pemFile) {
-
- sslContext = SSL_CTX_new(SSLv3_server_method());
- if (sslContext == NULL) {
- LogSSLError();
- return false;
- }
-
- if (SSL_CTX_use_certificate_file(sslContext, pemFile, SSL_FILETYPE_PEM) != 1) {
- LogSSLError();
- return false;
- }
-
- if (SSL_CTX_use_PrivateKey_file(sslContext, pemFile, SSL_FILETYPE_PEM) != 1) {
- LogSSLError();
- return false;
- }
-
- return true;
-}
/*
* cVdrmonClientSocket
*/
-cVdrmanagerClientSocket::cVdrmanagerClientSocket(const char * password) {
- readbuf = writebuf = "";
+cVdrmanagerClientSocket::cVdrmanagerClientSocket(const char * password, int compressionMode) {
+ readbuf = "";
+ writebuf = "";
+ sendbuf = NULL;
+ sendsize = 0;
+ sendoffset = 0;
disconnected = false;
+ initDisconnect = false;
client = ++clientno;
this->password = password;
+ this->compressionMode = compressionMode;
login = false;
+ compression = false;
+ initCompression = false;
}
cVdrmanagerClientSocket::~cVdrmanagerClientSocket() {
-
- if (sslContext) {
- SSL_free(sslContext);
- }
}
bool cVdrmanagerClientSocket::IsLineComplete() {
@@ -237,24 +195,13 @@ bool cVdrmanagerClientSocket::GetLine(string& line) {
}
bool cVdrmanagerClientSocket::Read() {
-
if (Disconnected())
return false;
int rc;
bool len = 0;
char buf[2001];
-
- for(;;) {
- if (useSSL) {
- rc = read(sock, buf, sizeof(buf)-1);
- } else {
- rc = SSL_read(sslContext, buf, sizeof(buf)-1);
- }
-
- if (rc <= 0)
- break;
-
+ while ((rc = read(sock, buf, sizeof(buf) - 1)) > 0) {
buf[rc] = 0;
readbuf += buf;
len += rc;
@@ -276,46 +223,74 @@ bool cVdrmanagerClientSocket::Disconnected() {
}
void cVdrmanagerClientSocket::Disconnect() {
- disconnected = true;
+ initDisconnect = true;
}
bool cVdrmanagerClientSocket::PutLine(string line) {
- //TODO http://projects.vdr-developer.org/issues/790
- //string line2 = cHelpers::compress_string(line);
- //unsigned long l = line.size();
- //unsigned long l2 = line2.size();
- //if(l2 == 0){
- //l2 = 1;
- //}
- //dsyslog("[vdrmanager] PutLine, line size is %lu, with zlib it would be %lu (factor %lu)", l, l2, l/l2);
- // add line to write buffer
- writebuf += line;
-
- // data present?
- if (writebuf.length() > 0) {
- int rc;
- if (useSSL) {
- rc = SSL_write(sslContext, writebuf.c_str(), writebuf.length());
- } else {
- rc = write(sock, writebuf.c_str(), writebuf.length());
- }
+
+ // fill writebuf
+ if (line.length() > 0) {
+ writebuf += line;
+ return true;
+ }
+
+ // initialize sendbuf if needed
+ if (sendbuf == NULL) {
+ if (!compression) {
+ sendbuf = (char *)malloc(writebuf.length()+1);
+ strcpy(sendbuf, writebuf.c_str());
+ sendsize = writebuf.length();
+ } else {
+ Compress();
+ }
+ sendoffset = 0;
+ writebuf.clear();
+ }
+
+ // send data
+ if (sendsize > 0) {
+
+ // write so many bytes as possible
+ int rc = write(sock, sendbuf + sendoffset, sendsize);
if (rc < 0 && errno != EAGAIN)
{
LOG_ERROR;
+
+ if (sendbuf != NULL) {
+ free(sendbuf);
+ sendbuf = NULL;
+ }
+
return false;
}
+ sendsize -= rc;
+ sendoffset += rc;
+ }
+
+ if (sendsize == 0) {
+
+ if (sendbuf != NULL) {
+ free(sendbuf);
+ sendbuf = NULL;
+ }
- // move the remainder
- if (rc > 0)
- writebuf = writebuf.substr(rc, writebuf.length() - rc);
+ if (initCompression) {
+ isyslog("Compression is activated now");
+ initCompression = false;
+ compression = true;
+ }
+
+ if (initDisconnect) {
+ initDisconnect = false;
+ disconnected = true;
+ }
}
return true;
}
bool cVdrmanagerClientSocket::Flush() {
- string empty = "";
- return PutLine(empty);
+ return PutLine("");
}
bool cVdrmanagerClientSocket::Attach(int fd) {
@@ -328,7 +303,7 @@ int cVdrmanagerClientSocket::GetClientId() {
}
bool cVdrmanagerClientSocket::WritePending() {
- return writebuf.length() > 0;
+ return sendsize > 0;
}
bool cVdrmanagerClientSocket::IsLoggedIn() {
@@ -339,20 +314,41 @@ void cVdrmanagerClientSocket::SetLoggedIn() {
login = true;
}
-bool::cVdrmanagerClientSocket::InitSSL(SSL_CTX * sslContext) {
-
- // create a new SSL context
- this->sslContext = SSL_new(sslContext);
- if (this->sslContext == NULL) {
- LOG_ERROR_STR("Error creating new SSL context");
- return false;
+void cVdrmanagerClientSocket::ActivateCompression() {
+
+ string mode = "NONE";
+ switch (compressionMode) {
+ case COMPRESSION_GZIP:
+ mode = "GZIP";
+ initCompression = true;
+ break;
+ case COMPRESSION_ZLIB:
+ mode = "ZLIB";
+ initCompression = true;
+ break;
+ default:
+ mode = "NONE";
+ break;
}
- // connect context to the socket
- if (SSL_set_fd(this->sslContext, sock) != 1) {
- SSL_free(this->sslContext);
- this->sslContext = NULL;
- LOG_ERROR_STR("Error connecting SSL and socket");
- return false;
+ PutLine("!OK " + mode + "\r\n");
+}
+
+void cVdrmanagerClientSocket::Compress() {
+ cCompressor compressor = cCompressor();
+
+ switch (compressionMode) {
+ case COMPRESSION_GZIP:
+ compressor.CompressGzip(writebuf);
+ break;
+ case COMPRESSION_ZLIB:
+ compressor.CompressZlib(writebuf);
+ break;
}
+
+ sendbuf = compressor.GetData();
+ sendsize = compressor.getDataSize();
+
+ double ratio = 1.0 * writebuf.length() / sendsize;
+ isyslog("Compression stats: raw %ld, compressed %ld, ratio %f:1", writebuf.length(), sendsize, ratio);
}