OverSim
AppTunOutScheduler Class Reference

#include <apptunoutscheduler.h>

Inheritance diagram for AppTunOutScheduler:
RealtimeScheduler

Public Member Functions

virtual ~AppTunOutScheduler ()
- Public Member Functions inherited from RealtimeScheduler
 RealtimeScheduler ()
 Constructor.
virtual ~RealtimeScheduler ()
 Destructor.
virtual void startRun ()
 Called at the beginning of a simulation run.
virtual void endRun ()
 Called at the end of a simulation run.
virtual void executionResumed ()
 Recalculates "base time" from current wall clock time.
virtual void setInterfaceModule (cModule *module, cMessage *notificationMsg, PacketBuffer *buffer, int mtu, bool isApp=false)
 To be called from the module which wishes to receive data from the tun device.
void registerSocket (SOCKET fd, cModule *mod, cMessage *notifMsg, PacketBuffer *buffer, int mtu)
virtual cMessage * getNextEvent ()
 Scheduler function – it comes from cScheduler interface.
void sendNotificationMsg (cMessage *msg, cModule *mod)
 send notification msg to module
virtual ssize_t sendBytes (const char *buf, size_t numBytes, sockaddr *addr=0, socklen_t addrlen=0, bool isApp=false, SOCKET fd=INVALID_SOCKET)
 Send data to network.
void closeAppSocket (SOCKET fd)
 Close the application TCP socket.
virtual SOCKET getAppTunFd ()
 Returns the FD for the application TUN socket.

Protected Member Functions

virtual int initializeNetwork ()
 Initialize the network.
virtual void additionalFD ()
 This function is called from main loop if data is accessible from "additional_fd".
- Protected Member Functions inherited from RealtimeScheduler
virtual bool receiveWithTimeout (long usec)
 Waits for incoming data on the tun device.
virtual int receiveUntil (const timeval &targetTime)
 Tries to read data until the given time is up.

Protected Attributes

char * dev
- Protected Attributes inherited from RealtimeScheduler
std::map< SOCKET, SocketContextsocketContextMap
fd_set all_fds
SOCKET maxfd
SOCKET netw_fd
SOCKET apptun_fd
cModule * module
cMessage * notificationMsg
PacketBufferpacketBuffer
size_t buffersize
cModule * appModule
cMessage * appNotificationMsg
PacketBufferappPacketBuffer
size_t appBuffersize
int appConnectionLimit
SOCKET additional_fd
timeval baseTime

Detailed Description

Definition at line 40 of file apptunoutscheduler.h.

Constructor & Destructor Documentation

AppTunOutScheduler::~AppTunOutScheduler ( )
virtual

Definition at line 33 of file apptunoutscheduler.cc.

{
if (additional_fd >= 0) {
#ifdef _WIN32
closesocket(additional_fd);
#else
close(additional_fd);
#endif
}
}

Member Function Documentation

void AppTunOutScheduler::additionalFD ( )
protectedvirtual

This function is called from main loop if data is accessible from "additional_fd".

This FD can be set in initializeNetwork by concrete implementations.

Reimplemented from RealtimeScheduler.

Definition at line 195 of file apptunoutscheduler.cc.

{
sockaddr* from = (sockaddr*) new sockaddr_in;
socklen_t addrlen = sizeof(sockaddr_in);
SOCKET new_sock = accept( additional_fd, from, &addrlen );
if (new_sock == INVALID_SOCKET) {
opp_warning("Error connecting to remote app");
return;
}
int count = 0;
for (SOCKET fd = 0; fd <= maxfd; fd++) {
if (fd == netw_fd) continue;
if (fd == additional_fd) continue;
if (FD_ISSET(fd, &all_fds)) count++;
}
if (count >= appConnectionLimit) {
// We already have too many connections to external applications
// "reject" connection
#ifdef _WIN32
closesocket(new_sock);
#else
close(new_sock);
#endif
ev << "[UdpOutScheduler::additionalFD()]\n"
<< " Rejecting new app connection (FD: " << new_sock << ")"
<< endl;
return;
}
}
FD_SET(new_sock, &all_fds);
if (new_sock > maxfd) {
maxfd = new_sock;
}
// Inform app about new connection
appPacketBuffer->push_back(PacketBufferEntry(0, 0, from, addrlen,
ev << "[UdpOutScheduler::additionalFD()]\n"
<< " Accepting new app connection (FD: " << new_sock << ")"
<< endl;
}
int AppTunOutScheduler::initializeNetwork ( )
protectedvirtual

Initialize the network.

Implements RealtimeScheduler.

Definition at line 44 of file apptunoutscheduler.cc.

{
#if defined _WIN32 || defined __APPLE__
throw cRuntimeError("TunOutSchedulter::initializeNetwork():"
"TUN interface not supported on Windows/Max OS!");
return -1;
#else
// get app port (0 if external app is not used)
int appPort = ev.getConfig()->getAsInt(CFGID_EXTERNALAPP_APP_PORT, 0);
// Initialize TCP socket for App communication if desired
if (appPort > 0) {
struct sockaddr_in server;
SOCKET sock;
// Waiting for a TCP connection
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
opp_error("Error creating socket");
return -1;
}
int on = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
memset(&server, 0, sizeof (server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(appPort);
if (bind( sock, (struct sockaddr*)&server, sizeof( server)) < 0) {
opp_error("Error binding to app socket");
return -1;
}
if (listen( sock, 5 ) == -1) {
opp_error("Error listening on app socket");
return -1;
}
// Set additional_fd so we will be called if data
// (i.e. connection requests) is available at sock
additional_fd = sock;
}
}
// Open UDP port
if (netw_fd != INVALID_SOCKET) {
// Port is already open, reuse it...
FD_SET(netw_fd, &all_fds);
if (netw_fd> maxfd) {
}
}
sockaddr_in addr;
netw_fd = socket(AF_INET, SOCK_DGRAM, 0);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
cModule* overlay = simulation.getModuleByPath(
"SingleHostUnderlayNetwork.overlayTerminal[0].overlay");
if (overlay == NULL) {
throw cRuntimeError("UdpOutScheduler::initializeNetwork(): "
"Overlay module not found!");
}
addr.sin_port = htons(overlay->gate("appIn")->getNextGate()->
getOwnerModule()->par("localPort").longValue());
cModule* underlayConfigurator =
simulation.getModuleByPath("SingleHostUnderlayNetwork.underlayConfigurator");
if (underlayConfigurator == NULL) {
throw cRuntimeError("UdpOutScheduler::initializeNetwork(): "
"UnderlayConfigurator module not found!");
}
if (strlen(underlayConfigurator->par("nodeIP").stringValue())) {
addr.sin_addr.s_addr = htonl(IPAddress(underlayConfigurator->
par("nodeIP").stringValue()).getInt());
} else {
addr.sin_addr.s_addr = htonl(INADDR_ANY);
}
if (bind( netw_fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
opp_error("Error binding to UDP socket");
return -1;
}
FD_SET(netw_fd, &all_fds);
if (netw_fd> maxfd) {
}
// Initialize TUN device for network communication
// see /usr/src/linux/Documentation/network/tuntap.txt
struct ifreq ifr;
int err;
dev = new char[IFNAMSIZ];
if (apptun_fd != INVALID_SOCKET) {
opp_error("Already bound to application TUN device!");
return -1;
}
if ((apptun_fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
opp_warning("Error opening application tun device");
return 0;
} else {
ev << "[AppTunOutScheduler::initializeNetwork()]\n"
<< "\t Successfully opened application TUN device"
<< endl;
}
memset(&ifr, 0, sizeof(ifr));
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_TAP - TAP device
*
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
strncpy(ifr.ifr_name, "tun%d", IFNAMSIZ);
if((err = ioctl(apptun_fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
close(apptun_fd);
opp_error("Error ioctl application tun device");
return -1;
}
strncpy(dev, ifr.ifr_name, IFNAMSIZ);
ev << "[AppTunOutScheduler::initializeNetwork()]\n"
<< " Bound to device " << dev << "\n"
<< " Remember to bring up application TUN device with "
<< "ifconfig before proceeding"
<< endl;
FD_SET(apptun_fd, &all_fds);
return 0;
#endif
}

Member Data Documentation

char* AppTunOutScheduler::dev
protected

Definition at line 43 of file apptunoutscheduler.h.

Referenced by initializeNetwork().


The documentation for this class was generated from the following files: