Socket.cpp 2.51 KB
Newer Older
/jdi/'s avatar
/jdi/ committed
1
2
3
4
5
6
7
/*
 * Socket.cpp
 *
 *  Created on: 02.09.2015
 *      Author: jdi
 */
#include <cstdlib>
/jdi/'s avatar
/jdi/ committed
8
#include <array>
/jdi/'s avatar
/jdi/ committed
9
10
11
12
13
#include <unistd.h>
#include "Socket.h"
#include "Packet.h"
#include "Options.h"
#include "Host.h"
/jdi/'s avatar
/jdi/ committed
14
#include "Types.h"
/jdi/'s avatar
/jdi/ committed
15

/jdi/'s avatar
/jdi/ committed
16
17
Socket::Socket(boost::asio::io_service& io_service) :
		send_socket_(io_service), receive_socket_(io_service), timer(io_service) {
/jdi/'s avatar
/jdi/ committed
18
}
/jdi/'s avatar
/jdi/ committed
19
//, resolver(				io_service)
/jdi/'s avatar
/jdi/ committed
20
void Socket::init(short dst_port, short src_port) {
21
22
	if (initialized)
		return;
/jdi/'s avatar
/jdi/ committed
23
24
25
26
27
28
29

	if (options.flags & FLAG_REVERSE) {
		short p = dst_port;
		dst_port = src_port;
		src_port = p;
	}

/jdi/'s avatar
/jdi/ committed
30
31
	if (options.flags & FLAG_DEBUG)
		std::cout << "Local IP:\t" << local_ip << "\n";
/jdi/'s avatar
/jdi/ committed
32

33

/jdi/'s avatar
/jdi/ committed
34
35
36
37
38
39
40
	wildcard_endpoint_ = boost::asio::ip::udp::endpoint(
			boost::asio::ip::address_v4::from_string("0.0.0.0"), src_port);
	local_endpoint_ = boost::asio::ip::udp::endpoint(
			boost::asio::ip::address_v4(local_ip), src_port);
	broadcast_endpoint_ = boost::asio::ip::udp::endpoint(
			boost::asio::ip::address_v4::from_string("255.255.255.255"),
			dst_port);
/jdi/'s avatar
/jdi/ committed
41

/jdi/'s avatar
/jdi/ committed
42
43
44
	send_socket_.open(boost::asio::ip::udp::v4());
	send_socket_.set_option(boost::asio::socket_base::broadcast(true));
	send_socket_.set_option(boost::asio::socket_base::reuse_address(true));
/jdi/'s avatar
/jdi/ committed
45
	send_socket_.bind(local_endpoint_);
/jdi/'s avatar
/jdi/ committed
46

/jdi/'s avatar
/jdi/ committed
47
48
49
	receive_socket_.open(boost::asio::ip::udp::v4());
	receive_socket_.set_option(boost::asio::socket_base::broadcast(true));
	receive_socket_.set_option(boost::asio::socket_base::reuse_address(true));
/jdi/'s avatar
/jdi/ committed
50
	receive_socket_.bind(wildcard_endpoint_);
/jdi/'s avatar
/jdi/ committed
51

/jdi/'s avatar
/jdi/ committed
52
53
54
55
56
57
58
59
60
61
62
	if (options.timeout != 0) {
		timer.expires_from_now(
				boost::posix_time::milliseconds(options.timeout));
		timer.async_wait([this](const boost::system::error_code& error)
		{
			if (!error)
			{
				receive_socket_.close();
			}
		});
	}
63
64

	initialized = 1;
/jdi/'s avatar
/jdi/ committed
65
66
}

/jdi/'s avatar
/jdi/ committed
67
void Socket::setHostIp(ipAddr ip) {
/jdi/'s avatar
/jdi/ committed
68
	local_ip = ip;
/jdi/'s avatar
/jdi/ committed
69
70
}

/jdi/'s avatar
/jdi/ committed
71
72
void Socket::send(bytes data) {
	unsigned char * a = &data[0];
/jdi/'s avatar
/jdi/ committed
73
	send_socket_.async_send_to(boost::asio::buffer(a, data.size()),
/jdi/'s avatar
/jdi/ committed
74
			broadcast_endpoint_,
/jdi/'s avatar
/jdi/ committed
75
			[this](boost::system::error_code ec, std::size_t bytes_sent)
/jdi/'s avatar
/jdi/ committed
76
77
78
79
80
81
82
			{
				listen();
			});
}

void Socket::listen() {
	data.resize(MAX_LENGTH);
/jdi/'s avatar
/jdi/ committed
83
	receive_socket_.async_receive_from(boost::asio::buffer(data, MAX_LENGTH),
/jdi/'s avatar
/jdi/ committed
84
			remote_endpoint_,
/jdi/'s avatar
/jdi/ committed
85
			[this](boost::system::error_code ec, std::size_t bytes_recvd)
/jdi/'s avatar
/jdi/ committed
86
87
			{
				if (ec || bytes_recvd == 0) {
/jdi/'s avatar
/jdi/ committed
88
89
					//listen();
					// TODO distinguish error codes
/jdi/'s avatar
/jdi/ committed
90
91
				} else {
					data.resize(bytes_recvd);
/jdi/'s avatar
/jdi/ committed
92
					Packet p = Packet(Packet::RETURN);
/jdi/'s avatar
/jdi/ committed
93
94
95
					p.encode(data);
					p.parse(data);
					if(!callback(p)) {
/jdi/'s avatar
/jdi/ committed
96
						//TODO do something
/jdi/'s avatar
/jdi/ committed
97
					}
/jdi/'s avatar
/jdi/ committed
98
					listen();
/jdi/'s avatar
/jdi/ committed
99
100
101
				}
			});
}