apptunoutscheduler.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "apptunoutscheduler.h"
00025 #include "IPvXAddress.h"
00026 #include <regmacros.h>
00027
00028 Register_Class(AppTunOutScheduler);
00029
00030
00031 extern cConfigOption *CFGID_EXTERNALAPP_APP_PORT;
00032
00033 AppTunOutScheduler::~AppTunOutScheduler()
00034 {
00035 if (additional_fd >= 0) {
00036 #ifdef _WIN32
00037 closesocket(additional_fd);
00038 #else
00039 close(additional_fd);
00040 #endif
00041 }
00042 }
00043
00044 int AppTunOutScheduler::initializeNetwork()
00045 {
00046 #if defined _WIN32 || defined __APPLE__
00047 throw cRuntimeError("TunOutSchedulter::initializeNetwork():"
00048 "TUN interface not supported on Windows/Max OS!");
00049 return -1;
00050 #else
00051
00052 int appPort = ev.getConfig()->getAsInt(CFGID_EXTERNALAPP_APP_PORT, 0);
00053
00054
00055 if (appPort > 0) {
00056
00057 struct sockaddr_in server;
00058 SOCKET sock;
00059
00060
00061 sock = socket(AF_INET, SOCK_STREAM, 0);
00062
00063 if (sock == INVALID_SOCKET) {
00064 opp_error("Error creating socket");
00065 return -1;
00066 }
00067
00068 int on = 1;
00069 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
00070
00071 memset(&server, 0, sizeof (server));
00072 server.sin_family = AF_INET;
00073 server.sin_addr.s_addr = htonl(INADDR_ANY);
00074 server.sin_port = htons(appPort);
00075
00076 if (bind( sock, (struct sockaddr*)&server, sizeof( server)) < 0) {
00077 opp_error("Error binding to app socket");
00078 return -1;
00079 }
00080
00081 if (listen( sock, 5 ) == -1) {
00082 opp_error("Error listening on app socket");
00083 return -1;
00084 }
00085
00086
00087 additional_fd = sock;
00088 FD_SET(additional_fd, &all_fds);
00089 if (additional_fd > maxfd) {
00090 maxfd = additional_fd;
00091 }
00092 }
00093
00094
00095 if (netw_fd != INVALID_SOCKET) {
00096
00097 FD_SET(netw_fd, &all_fds);
00098
00099 if (netw_fd> maxfd) {
00100 maxfd = netw_fd;
00101 }
00102 }
00103
00104 sockaddr_in addr;
00105 netw_fd = socket(AF_INET, SOCK_DGRAM, 0);
00106 memset(&addr, 0, sizeof(addr));
00107 addr.sin_family = AF_INET;
00108
00109 cModule* overlay = simulation.getModuleByPath(
00110 "SingleHostUnderlayNetwork.overlayTerminal[0].overlay");
00111
00112 if (overlay == NULL) {
00113 throw cRuntimeError("UdpOutScheduler::initializeNetwork(): "
00114 "Overlay module not found!");
00115 }
00116
00117 addr.sin_port = htons(overlay->gate("appIn")->getNextGate()->
00118 getOwnerModule()->par("localPort").longValue());
00119
00120 cModule* underlayConfigurator =
00121 simulation.getModuleByPath("SingleHostUnderlayNetwork.underlayConfigurator");
00122
00123 if (underlayConfigurator == NULL) {
00124 throw cRuntimeError("UdpOutScheduler::initializeNetwork(): "
00125 "UnderlayConfigurator module not found!");
00126 }
00127
00128 if (strlen(underlayConfigurator->par("nodeIP").stringValue())) {
00129 addr.sin_addr.s_addr = htonl(IPAddress(underlayConfigurator->
00130 par("nodeIP").stringValue()).getInt());
00131 } else {
00132 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00133 }
00134
00135 if (bind( netw_fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
00136 opp_error("Error binding to UDP socket");
00137 return -1;
00138 }
00139
00140 FD_SET(netw_fd, &all_fds);
00141
00142 if (netw_fd> maxfd) {
00143 maxfd = netw_fd;
00144 }
00145
00146
00147
00148 struct ifreq ifr;
00149 int err;
00150 dev = new char[IFNAMSIZ];
00151
00152 if (apptun_fd != INVALID_SOCKET) {
00153 opp_error("Already bound to application TUN device!");
00154 return -1;
00155 }
00156
00157 if ((apptun_fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
00158 opp_warning("Error opening application tun device");
00159 return 0;
00160 } else {
00161 ev << "[AppTunOutScheduler::initializeNetwork()]\n"
00162 << "\t Successfully opened application TUN device"
00163 << endl;
00164 }
00165
00166 memset(&ifr, 0, sizeof(ifr));
00167
00168
00169
00170
00171
00172
00173 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
00174 strncpy(ifr.ifr_name, "tun%d", IFNAMSIZ);
00175
00176 if((err = ioctl(apptun_fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
00177 close(apptun_fd);
00178 opp_error("Error ioctl application tun device");
00179 return -1;
00180 }
00181
00182 strncpy(dev, ifr.ifr_name, IFNAMSIZ);
00183 ev << "[AppTunOutScheduler::initializeNetwork()]\n"
00184 << " Bound to device " << dev << "\n"
00185 << " Remember to bring up application TUN device with "
00186 << "ifconfig before proceeding"
00187 << endl;
00188
00189 FD_SET(apptun_fd, &all_fds);
00190 if( apptun_fd> maxfd ) maxfd = apptun_fd;
00191 return 0;
00192 #endif
00193 }
00194
00195 void AppTunOutScheduler::additionalFD() {
00196 sockaddr* from = (sockaddr*) new sockaddr_in;
00197 socklen_t addrlen = sizeof(sockaddr_in);
00198
00199 SOCKET new_sock = accept( additional_fd, from, &addrlen );
00200
00201 if (new_sock == INVALID_SOCKET) {
00202 opp_warning("Error connecting to remote app");
00203 return;
00204 }
00205
00206 if (appConnectionLimit) {
00207 int count = 0;
00208
00209 for (SOCKET fd = 0; fd <= maxfd; fd++) {
00210 if (fd == netw_fd) continue;
00211 if (fd == additional_fd) continue;
00212 if (FD_ISSET(fd, &all_fds)) count++;
00213 }
00214
00215 if (count >= appConnectionLimit) {
00216
00217
00218 #ifdef _WIN32
00219 closesocket(new_sock);
00220 #else
00221 close(new_sock);
00222 #endif
00223 ev << "[UdpOutScheduler::additionalFD()]\n"
00224 << " Rejecting new app connection (FD: " << new_sock << ")"
00225 << endl;
00226
00227 return;
00228 }
00229 }
00230
00231 FD_SET(new_sock, &all_fds);
00232
00233 if (new_sock > maxfd) {
00234 maxfd = new_sock;
00235 }
00236
00237
00238 appPacketBuffer->push_back(PacketBufferEntry(0, 0, from, addrlen,
00239 PacketBufferEntry::PACKET_FD_NEW, new_sock));
00240
00241 sendNotificationMsg(appNotificationMsg, appModule);
00242
00243 ev << "[UdpOutScheduler::additionalFD()]\n"
00244 << " Accepting new app connection (FD: " << new_sock << ")"
00245 << endl;
00246 }