jsocketoption.cpp 7.42 KB
/***************************************************************************
 *   Copyright (C) 2005 by Jeff Ferr                                       *
 *   root@sat                                                              *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "jsocketoption.h"
#include "jsocketoptionexception.h"

#include <sys/ioctl.h>
#include <netinet/in.h>
#include <fcntl.h>

namespace jsocket {

SocketOption::SocketOption(int16_t fd_, socket_type_t type_)
{
	_fd = fd_;
	_type = type_;
}

SocketOption::~SocketOption()
{
}

void SocketOption::SetKeepAlive(bool b_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_KEEPALIVE, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set keep alive error !");
	}
}

void SocketOption::SetOutOfBandInLine(bool b_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_OOBINLINE, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set out of band error !");
	}
}

void SocketOption::SetSendTimeOut(struct socket_time_t t_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_SNDTIMEO, &t_, sizeof(socket_time_t)) < 0) {
		throw SocketOptionException("Set send timeout error !");
	}
}

void SocketOption::SetReceiveTimeOut(struct socket_time_t t_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_RCVTIMEO, &t_, sizeof(socket_time_t)) < 0) {
		throw SocketOptionException("Set receive timeout error !");
	}
}

void SocketOption::SetPassCredentials(bool b_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set pass credentials error !");
	}
}

void SocketOption::GetPeerCredentials(void *v_)
{
	/*
	if (getsockopt(_fd, SOL_SOCKET, SO_PEERCRED, &v_, sizeof(v_)) < 0) {
		throw SocketOptionException("Set peer credentials error !");
	}
	*/
}

void SocketOption::BindToDevice(std::string dev_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_BINDTODEVICE, dev_.c_str(), dev_.size()+1) < 0) {
		throw SocketOptionException("Bind to device error !");
	}
}

void SocketOption::SetReuseAddress(bool b_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set reuse address error !");
	}
}

void SocketOption::SetReusePort(bool b_)
{
	#ifndef SO_REUSEPORT
		#define SO_REUSEPORT 15
	#endif
	
	if (setsockopt(_fd, SOL_SOCKET, SO_REUSEPORT, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set reuse port error !");
	}
}

void SocketOption::GetSocketType(socket_type_t *type_)
{
	(*type_) = _type;
}

bool SocketOption::GetSocketAcceptConnection()
{
	socklen_t length;
	bool b;
	
	if (getsockopt(_fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &length) < 0) {
		throw SocketOptionException("Get socket accept connection error !");
	}

	return b;
}

void SocketOption::SetRoute(bool b_)
{
	b_ = (b_ == true)?false:true;
	
	if (setsockopt(_fd, SOL_SOCKET, SO_DONTROUTE, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set route error !");
	}
}

void SocketOption::SetBroadcast(bool b_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_BROADCAST, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set broadcast error !");
	}
}

void SocketOption::SetSendMaximumBuffer(uint32_t length_)
{
	length_ /= 2;

	if (setsockopt(_fd, SOL_SOCKET, SO_SNDBUF, &length_, sizeof(uint32_t)) < 0) {
		throw SocketOptionException("Set send maximum buffer error !");
	}
}

void SocketOption::SetReceiveMaximumBuffer(uint32_t length_)
{
	length_ /= 2;
	
	if (setsockopt(_fd, SOL_SOCKET, SO_RCVBUF, &length_, sizeof(uint32_t)) < 0) {
		throw SocketOptionException("Set receive maximum buffer error !");
	}
}

uint32_t SocketOption::GetSendMaximumBuffer()
{
	socklen_t length;
	uint32_t l = 0;

	if (getsockopt(_fd, SOL_SOCKET, SO_SNDBUF, &l, &length) < 0) {
		throw SocketOptionException("Get send maximum buffer error !");
	}

	return l;
}

uint32_t SocketOption::GetReceiveMaximumBuffer()
{
	socklen_t length;
	uint32_t l = 0;
	
	if (getsockopt(_fd, SOL_SOCKET, SO_RCVBUF, &l, &length) < 0) {
		throw SocketOptionException("Get receive maximum buffer error !");
	}

	return l;
}

void SocketOption::SetLinger(bool on, int16_t linger_)
{
	struct linger l;

	l.l_onoff = on;
	l.l_linger = linger_;
	
	if (setsockopt(_fd, SOL_SOCKET, SO_LINGER, &l, sizeof(struct linger)) < 0) {
		throw SocketOptionException("Set linger error !");
	}
}

void SocketOption::SetPriority(uint16_t p_)
{
	if (setsockopt(_fd, SOL_SOCKET, SO_PRIORITY, &p_, sizeof(uint16_t)) < 0) {
		throw SocketOptionException("Set priority error !");
	}
}

void SocketOption::ClearPendingSocketError()
{
	bool b = true;
	
	if (setsockopt(_fd, SOL_SOCKET, SO_ERROR, &b, sizeof(bool)) < 0) {
		throw SocketOptionException("Clean pending socket errors error !");
	}
}

void SocketOption::SetSocketBlocking()
{
	if (fcntl(_fd, F_SETFL, O_NONBLOCK) < 0) {
		throw SocketOptionException("Set socket blocking error !");
	}
}

void SocketOption::SetTypeOfService(uint16_t t_)
{
	if (setsockopt(_fd, IPPROTO_IP, IP_TOS, (char *)&t_, sizeof(uint16_t)) < 0) {
		throw SocketOptionException("Set type of service error !");
	}
}

void SocketOption::SetTimeToLive(uint16_t t_)
{
	if (setsockopt(_fd, IPPROTO_IP, IP_TTL, (char *)&t_, sizeof(uint16_t)) < 0) {
		throw SocketOptionException("Set time to live error !");
	}
}

void SocketOption::SetHeaderInclude(bool b_)
{
	if (setsockopt(_fd, IPPROTO_IP, IP_HDRINCL, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set header include error !");
	}
}

void SocketOption::GetTimeStamp(struct socket_time_t t_)
{
	if (ioctl(_fd, SIOCGSTAMP, &t_) < 0) {
		throw SocketOptionException("Get time stamp error !");
	}
}

void SocketOption::SetIOSynchronized(bool b_)
{
	if (ioctl(_fd, FIOASYNC, b_) < 0) {
		throw SocketOptionException("Set io synchronized error !");
	}
}

void SocketOption::SetMulticastLoop(bool b_)
{
	if (_type != SOCK_MCAST) {
		return;
	}
	
	if (setsockopt(_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &b_, sizeof(bool)) < 0) {
		throw SocketOptionException("Set multicast loop error !");
	}
}

void SocketOption::SetRSVP(int t_)
{
	if (_type != SOCK_MCAST) {
		return;
	}

	/*
	if (setsockopt(_fd, IPPROTO_IP, IP_MULTICAST_VIF, &t_, sizeof(int)) < 0) {
		throw SocketOptionException("Set rsvp error !");
	}
	*/
}

};