#include <tunoutscheduler.h>
Public Member Functions | |
virtual | ~TunOutScheduler () |
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 Attributes | |
char * | dev |
TunOutScheduler::~TunOutScheduler | ( | ) | [virtual] |
00029 { 00030 if (additional_fd >= 0) { 00031 close(additional_fd); 00032 } 00033 00034 delete dev; 00035 }
int TunOutScheduler::initializeNetwork | ( | ) | [protected, virtual] |
Initialize the network.
Implements RealtimeScheduler.
00039 { 00040 // Initialize TUN device for network communication 00041 // see /usr/src/linux/Documentation/network/tuntap.txt 00042 struct ifreq ifr; 00043 int err; 00044 dev = new char[IFNAMSIZ]; 00045 00046 // get app port (0 if external app is not used) 00047 int appPort = ev.config()->getAsInt("ExternalApp", "app-port"); 00048 00049 // Initialize TCP socket for App communication if desired 00050 if ( appPort > 0 ) { 00051 00052 struct sockaddr_in server; 00053 int sock; 00054 00055 // Waiting for a TCP connection 00056 // WARNING: Will only accept exactly ONE app connecting to the socket 00057 sock = socket( AF_INET, SOCK_STREAM, 0 ); 00058 if (sock < 0) { 00059 opp_error("Error creating socket"); 00060 return -1; 00061 } 00062 00063 int on = 1; 00064 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 00065 00066 memset( &server, 0, sizeof (server)); 00067 server.sin_family = AF_INET; 00068 server.sin_addr.s_addr = htonl( INADDR_ANY ); 00069 server.sin_port = htons( appPort ); 00070 00071 if(bind( sock, (struct sockaddr*)&server, sizeof( server)) < 0) { 00072 opp_error("Error binding to app socket"); 00073 return -1; 00074 } 00075 if( listen( sock, 5 ) == -1 ) { 00076 opp_error("Error listening on app socket"); 00077 return -1; 00078 } 00079 // Set additional_fd so we will be called if data 00080 // (i.e. connection requests) is available at sock 00081 additional_fd = sock; 00082 FD_SET(additional_fd, &all_fds); 00083 if( additional_fd > maxfd ) maxfd = additional_fd; 00084 } 00085 00086 if (netw_fd > 0) { 00087 opp_error("Already bound to TUN device!"); 00088 return -1; 00089 } 00090 if( (netw_fd = open("/dev/net/tun", O_RDWR)) < 0 ) { 00091 opp_warning("Error opening tun device"); 00092 return 0; 00093 } else { 00094 ev << "[TunOutScheduler::initializeNetwork()]\n" 00095 << "\t Successfully opened TUN device" 00096 << endl; 00097 } 00098 00099 memset(&ifr, 0, sizeof(ifr)); 00100 00101 /* Flags: IFF_TUN - TUN device (no Ethernet headers) 00102 * IFF_TAP - TAP device 00103 * 00104 * IFF_NO_PI - Do not provide packet information 00105 */ 00106 ifr.ifr_flags = IFF_TUN | IFF_NO_PI; 00107 strncpy(ifr.ifr_name, "tun%d", IFNAMSIZ); 00108 00109 if((err = ioctl(netw_fd, TUNSETIFF, (void *) &ifr)) < 0 ) { 00110 close(netw_fd); 00111 opp_error("Error ioctl tun device"); 00112 return -1; 00113 } 00114 strncpy(dev, ifr.ifr_name, IFNAMSIZ); 00115 ev << "[TunOutScheduler::initializeNetwork()]\n" 00116 << " Bound to device " << dev << "\n" 00117 << " Remember to bring up TUN device with ifconfig before proceeding" 00118 << endl; 00119 FD_SET(netw_fd, &all_fds); 00120 if( netw_fd> maxfd ) maxfd = netw_fd; 00121 return 0; 00122 }
void TunOutScheduler::additionalFD | ( | ) | [protected, virtual] |
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.
00124 { 00125 int new_sock = accept( additional_fd, 0, 0 ); 00126 if (new_sock < 0) { 00127 opp_warning("Error connecting to remote app"); 00128 return; 00129 } 00130 if ( appConnectionLimit ) { 00131 int count = 0; 00132 for ( int fd = 0; fd < maxfd; fd++ ) { 00133 if( fd == netw_fd ) continue; 00134 if( fd == additional_fd ) continue; 00135 if( FD_ISSET(fd, &all_fds)) count++; 00136 } 00137 if( count > appConnectionLimit ) { 00138 // We already have too many connections to external applications 00139 // "reject" connection 00140 close(new_sock); 00141 ev << "[UdpOutScheduler::additionalFD()]\n" 00142 << " Rejecting new app connection (FD: " << new_sock << ")" 00143 << endl; 00144 return; 00145 } 00146 } 00147 00148 FD_SET(new_sock, &all_fds); 00149 if( new_sock > maxfd ) maxfd = new_sock; 00150 00151 // Inform app about new connection 00152 appPacketBuffer->push_back(PacketBufferEntry(0, 0, PacketBufferEntry::FD_NEW, new_sock)); 00153 sendNotificationMsg(appNotificationMsg, appModule); 00154 00155 ev << "[UdpOutScheduler::additionalFD()]\n" 00156 << " Accepting new app connection (FD: " << new_sock << ")" 00157 << endl; 00158 00159 }
char* TunOutScheduler::dev [protected] |
Referenced by initializeNetwork(), and ~TunOutScheduler().