tunoutscheduler.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 "tunoutscheduler.h"
00025
00026 Register_Class(TunOutScheduler);
00027
00028
00029 extern cConfigOption *CFGID_EXTERNALAPP_APP_PORT;
00030
00031 TunOutScheduler::~TunOutScheduler()
00032 {
00033 if (additional_fd >= 0) {
00034 #ifdef _WIN32
00035 closesocket(additional_fd);
00036 #else
00037 close(additional_fd);
00038 #endif
00039 }
00040
00041 delete dev;
00042 }
00043
00044
00045 int TunOutScheduler::initializeNetwork()
00046 {
00047 #if defined _WIN32 || defined __APPLE__
00048 throw cRuntimeError("TunOutSchedulter::initializeNetwork():"
00049 "TUN interface not supported on Windows/Max OS!");
00050 return -1;
00051 #else
00052
00053
00054 struct ifreq ifr;
00055 int err;
00056 dev = new char[IFNAMSIZ];
00057
00058
00059 int appPort = ev.getConfig()->getAsInt(CFGID_EXTERNALAPP_APP_PORT, 0);
00060
00061
00062 if (appPort > 0) {
00063 struct sockaddr_in server;
00064 SOCKET sock;
00065
00066
00067
00068 sock = socket( AF_INET, SOCK_STREAM, 0 );
00069 if (sock == INVALID_SOCKET) {
00070 opp_error("Error creating socket");
00071 return -1;
00072 }
00073
00074 int on = 1;
00075 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
00076
00077 memset( &server, 0, sizeof (server));
00078 server.sin_family = AF_INET;
00079 server.sin_addr.s_addr = htonl( INADDR_ANY );
00080 server.sin_port = htons( appPort );
00081
00082 if (bind( sock, (struct sockaddr*)&server, sizeof( server)) < 0) {
00083 opp_error("Error binding to app socket");
00084 return -1;
00085 }
00086 if (listen( sock, 5 ) == -1 ) {
00087 opp_error("Error listening on app socket");
00088 return -1;
00089 }
00090
00091
00092 additional_fd = sock;
00093 FD_SET(additional_fd, &all_fds);
00094 if (additional_fd > maxfd) maxfd = additional_fd;
00095 }
00096
00097 if (netw_fd != INVALID_SOCKET) {
00098 opp_error("Already bound to TUN device!");
00099 return -1;
00100 }
00101
00102 if ((netw_fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
00103 opp_warning("Error opening tun device");
00104 return 0;
00105 } else {
00106 ev << "[TunOutScheduler::initializeNetwork()]\n"
00107 << "\t Successfully opened TUN device"
00108 << endl;
00109 }
00110
00111 memset(&ifr, 0, sizeof(ifr));
00112
00113
00114
00115
00116
00117
00118 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
00119 strncpy(ifr.ifr_name, "tun%d", IFNAMSIZ);
00120
00121 if((err = ioctl(netw_fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
00122 close(netw_fd);
00123 opp_error("Error ioctl tun device");
00124 return -1;
00125 }
00126
00127 strncpy(dev, ifr.ifr_name, IFNAMSIZ);
00128 ev << "[TunOutScheduler::initializeNetwork()]\n"
00129 << " Bound to device " << dev << "\n"
00130 << " Remember to bring up TUN device with ifconfig before proceeding"
00131 << endl;
00132
00133 FD_SET(netw_fd, &all_fds);
00134 if( netw_fd> maxfd ) maxfd = netw_fd;
00135 return 0;
00136 #endif
00137 }
00138
00139 void TunOutScheduler::additionalFD() {
00140 sockaddr* from = (sockaddr*) new sockaddr_in;
00141 socklen_t addrlen = sizeof(sockaddr_in);
00142
00143 SOCKET new_sock = accept( additional_fd, 0, 0 );
00144 if (new_sock == INVALID_SOCKET) {
00145 opp_warning("Error connecting to remote app");
00146 return;
00147 }
00148 if (appConnectionLimit) {
00149 int count = 0;
00150 for (SOCKET fd = 0; fd < maxfd; fd++) {
00151 if( fd == netw_fd ) continue;
00152 if( fd == additional_fd ) continue;
00153 if( FD_ISSET(fd, &all_fds)) count++;
00154 }
00155 if( count > appConnectionLimit ) {
00156
00157
00158 close(new_sock);
00159 ev << "[UdpOutScheduler::additionalFD()]\n"
00160 << " Rejecting new app connection (FD: " << new_sock << ")"
00161 << endl;
00162 return;
00163 }
00164 }
00165
00166 FD_SET(new_sock, &all_fds);
00167 if( new_sock > maxfd ) maxfd = new_sock;
00168
00169
00170 appPacketBuffer->push_back(PacketBufferEntry(0, 0, from, addrlen,
00171 PacketBufferEntry::PACKET_FD_NEW, new_sock));
00172 sendNotificationMsg(appNotificationMsg, appModule);
00173
00174 ev << "[UdpOutScheduler::additionalFD()]\n"
00175 << " Accepting new app connection (FD: " << new_sock << ")"
00176 << endl;
00177
00178 }
00179