Skip to content

Commit

Permalink
added Socket class
Browse files Browse the repository at this point in the history
Signed-off-by: Tolga Cakir <tolga@cevel.net>
  • Loading branch information
tolga9009 committed Jun 2, 2016
1 parent ee37379 commit ad27d60
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 82 deletions.
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ int main(int argc, char *argv[]) {

break;
case Format::Socket:
if (streamer.enableSocket(ip, port)) {
if (streamer.socket.enable(ip, port)) {
return EXIT_FAILURE;
}

Expand Down
106 changes: 106 additions & 0 deletions src/socket.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/**
* Copyright (c) 2014 - 2016 Tolga Cakir <tolga@cevel.net>
*
* This source file is part of Sidewinder daemon and is distributed under the
* MIT License. For more information, see LICENSE file.
*/

#include <csignal>
#include <iostream>

#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/stat.h>

#include <socket.hpp>

int Socket::enable(std::string ip, std::string port) {
struct addrinfo hints = {};
struct addrinfo *result, *entry;

hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;

// if <ip> is unconfigured, set it to nullptr, effectively IP 0.0.0.0
const char *ipAddress;

if (ip.empty()) {
ipAddress = nullptr;
} else {
ipAddress = ip.c_str();
}

auto ret = getaddrinfo(ipAddress, port.c_str(), &hints, &result);

if (ret) {
std::cerr << "Socket error: " << gai_strerror(ret) << std::endl;

return 1;
}

for (entry = result; entry != nullptr; entry = entry->ai_next) {
fd_ = socket(entry->ai_family, entry->ai_socktype, entry->ai_protocol);

if (fd_ < 0) {
// error, try next iteration
continue;
}

if (connect(fd_, entry->ai_addr, entry->ai_addrlen) != -1) {
// success
break;
}

close(fd_);
fd_ = -1;

return 1;
}

freeaddrinfo(result);

auto flags = fcntl(fd_, F_GETFL);

if (flags == -1) {
std::cerr << "Socket error: fcntl get flags." << std::endl;

return 1;
}

flags |= O_NONBLOCK;

if (fcntl(fd_, F_SETFL, flags) == -1) {
std::cerr << "Socket error: fcntl set flags." << std::endl;

return 1;
}

return 0;
}

void Socket::disable() {
if (fd_ != -1) {
close(fd_);
fd_ = -1;
}
}

void Socket::output(std::array<unsigned char, DATA_BUF> *buffer) {
if (fd_ == -1) {
return;
}

write(fd_, buffer->data(), buffer->size());
}

Socket::Socket() {
fd_ = -1;
}

Socket::~Socket() {
disable();
}
29 changes: 29 additions & 0 deletions src/socket.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (c) 2014 - 2016 Tolga Cakir <tolga@cevel.net>
*
* This source file is part of Sidewinder daemon and is distributed under the
* MIT License. For more information, see LICENSE file.
*/

#ifndef SOCKET_CLASS_H
#define SOCKET_CLASS_H

#include <array>
#include <string>

#include <gchd.hpp>

class Socket {
public:
int enable(std::string ip, std::string port);
void disable();
void output(std::array<unsigned char, DATA_BUF> *buffer);
Socket();
~Socket();

private:
int fd_;
std::string output_;
};

#endif
79 changes: 1 addition & 78 deletions src/streamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,78 +35,6 @@ void Streamer::disableDisk() {
}
}

int Streamer::enableSocket(std::string ip, std::string port) {
struct addrinfo hints = {};
struct addrinfo *result, *entry;

hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;

// if <ip> is unconfigured, set it to nullptr, effectively IP 0.0.0.0
const char *ipAddress;

if (ip.empty()) {
ipAddress = nullptr;
} else {
ipAddress = ip.c_str();
}

auto ret = getaddrinfo(ipAddress, port.c_str(), &hints, &result);

if (ret) {
std::cerr << "Socket error: " << gai_strerror(ret) << std::endl;

return 1;
}

for (entry = result; entry != nullptr; entry = entry->ai_next) {
socketFd_ = socket(entry->ai_family, entry->ai_socktype, entry->ai_protocol);

if (socketFd_ < 0) {
// error, try next iteration
continue;
}

if (connect(socketFd_, entry->ai_addr, entry->ai_addrlen) != -1) {
// success
break;
}

close(socketFd_);
socketFd_ = -1;

return 1;
}

freeaddrinfo(result);

auto flags = fcntl(socketFd_, F_GETFL);

if (flags == -1) {
std::cerr << "Socket error: fcntl get flags." << std::endl;

return 1;
}

flags |= O_NONBLOCK;

if (fcntl(socketFd_, F_SETFL, flags) == -1) {
std::cerr << "Socket error: fcntl set flags." << std::endl;

return 1;
}

return 0;
}

void Streamer::disableSocket() {
if (socketFd_ != -1) {
close(socketFd_);
socketFd_ = -1;
}
}

void Streamer::loop() {
std::array<unsigned char, DATA_BUF> buffer;

Expand All @@ -120,20 +48,15 @@ void Streamer::loop() {
}

fifo.output(&buffer);

if (socketFd_ != -1) {
write(socketFd_, buffer.data(), buffer.size());
}
socket.output(&buffer);
}
}

Streamer::Streamer(GCHD *gchd, Process *process) {
socketFd_ = -1;
gchd_ = gchd;
process_ = process;
}

Streamer::~Streamer() {
disableDisk();
disableSocket();
}
5 changes: 2 additions & 3 deletions src/streamer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,19 @@
#include <fifo.hpp>
#include <gchd.hpp>
#include <process.hpp>
#include <socket.hpp>

class Streamer {
public:
int enableDisk(std::string diskPath);
void disableDisk();
int enableSocket(std::string ip, std::string port);
void disableSocket();
void loop();
Fifo fifo;
Socket socket;
Streamer(GCHD *gchd, Process *process);
~Streamer();

private:
int socketFd_;
std::ofstream diskStream_;
GCHD *gchd_;
Process *process_;
Expand Down

0 comments on commit ad27d60

Please sign in to comment.