/*
- * Copyright (C) 2006-2010 Tobias Brunner
+ * Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
*/
status_t (*send) (socket_t *this, packet_t *packet);
+ /**
+ * Get the port this socket is listening on.
+ *
+ * @param nat_t TRUE to get the port used to float in case of NAT-T
+ * @return the port
+ */
+ u_int16_t (*get_port) (socket_t *this, bool nat_t);
+
/**
* Destroy a socket implementation.
*/
/*
- * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 2010-2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
return status;
}
+METHOD(socket_manager_t, get_port, u_int16_t,
+ private_socket_manager_t *this, bool nat_t)
+{
+ u_int16_t port = 0;
+ this->lock->read_lock(this->lock);
+ if (this->socket)
+ {
+ port = this->socket->get_port(this->socket, nat_t);
+ }
+ this->lock->unlock(this->lock);
+ return port;
+}
+
static void create_socket(private_socket_manager_t *this)
{
socket_constructor_t create;
.public = {
.send = _sender,
.receive = _receiver,
+ .get_port = _get_port,
.add_socket = _add_socket,
.remove_socket = _remove_socket,
.destroy = _destroy,
/*
- * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 2010-2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*/
status_t (*send) (socket_manager_t *this, packet_t *packet);
+ /**
+ * Get the port the registered socket is listening on.
+ *
+ * @param nat_t TRUE to get the port used to float in case of NAT-T
+ * @return the port, or 0, if no socket is registered
+ */
+ u_int16_t (*get_port) (socket_manager_t *this, bool nat_t);
+
/**
* Register a socket constructor.
*
/* send data */
sport = src->get_port(src);
family = dst->get_family(dst);
- if (sport == CHARON_UDP_PORT)
+ if (sport == 0 || sport == CHARON_UDP_PORT)
{
if (family == AF_INET)
{
return SUCCESS;
}
+METHOD(socket_t, get_port, u_int16_t,
+ private_socket_default_socket_t *this, bool nat_t)
+{
+ return nat_t ? CHARON_NATT_PORT : CHARON_UDP_PORT;
+}
+
/**
* open a socket to send and receive packets
*/
.socket = {
.send = _sender,
.receive = _receiver,
+ .get_port = _get_port,
.destroy = _destroy,
},
},
dst = packet->get_destination(packet);
family = src->get_family(src);
port = src->get_port(src);
+ port = port ?: CHARON_UDP_PORT;
skt = find_socket(this, family, port);
if (!skt)
{
return SUCCESS;
}
+METHOD(socket_t, get_port, u_int16_t,
+ private_socket_dynamic_socket_t *this, bool nat_t)
+{
+ /* we return 0 here for users that have no explicit port configured, the
+ * sender will default to the default port in this case */
+ return 0;
+}
+
METHOD(socket_t, destroy, void,
private_socket_dynamic_socket_t *this)
{
.socket = {
.send = _sender,
.receive = _receiver,
+ .get_port = _get_port,
.destroy = _destroy,
},
},
/* send data */
sport = src->get_port(src);
family = dst->get_family(dst);
- if (sport == CHARON_UDP_PORT)
+ if (sport == 0 || sport == CHARON_UDP_PORT)
{
if (family == AF_INET)
{
return skt;
}
+METHOD(socket_t, get_port, u_int16_t,
+ private_socket_raw_socket_t *this, bool nat_t)
+{
+ return nat_t ? CHARON_NATT_PORT : CHARON_UDP_PORT;
+}
+
/**
* open a socket to receive packets
*/
.socket = {
.send = _sender,
.receive = _receiver,
+ .get_port = _get_port,
.destroy = _destroy,
},
},