#include <udpoutscheduler.h>
Public Member Functions | |
virtual | ~UdpOutScheduler () |
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 |
UdpOutScheduler::~UdpOutScheduler | ( | ) | [virtual] |
00030 { 00031 if (additional_fd >= 0) { 00032 close(additional_fd); 00033 } 00034 00035 delete[] dev; 00036 }
int UdpOutScheduler::initializeNetwork | ( | ) | [protected, virtual] |
Initialize the network.
Implements RealtimeScheduler.
00039 { 00040 dev = new char[IFNAMSIZ]; 00041 00042 // get app port (0 if external app is not used) 00043 int appPort = ev.config()->getAsInt("ExternalApp", "app-port"); 00044 00045 // Initialize TCP socket for App communication if desired 00046 if (appPort > 0) { 00047 00048 struct sockaddr_in server; 00049 int sock; 00050 00051 // Waiting for a TCP connection 00052 // WARNING: Will only accept exactly ONE app connecting to the socket 00053 sock = socket(AF_INET, SOCK_STREAM, 0); 00054 00055 if (sock < 0) { 00056 opp_error("Error creating socket"); 00057 return -1; 00058 } 00059 00060 int on = 1; 00061 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 00062 00063 memset(&server, 0, sizeof (server)); 00064 server.sin_family = AF_INET; 00065 server.sin_addr.s_addr = htonl(INADDR_ANY); 00066 server.sin_port = htons(appPort); 00067 00068 if (bind( sock, (struct sockaddr*)&server, sizeof( server)) < 0) { 00069 opp_error("Error binding to app socket"); 00070 return -1; 00071 } 00072 00073 if (listen( sock, 5 ) == -1) { 00074 opp_error("Error listening on app socket"); 00075 return -1; 00076 } 00077 // Set additional_fd so we will be called if data 00078 // (i.e. connection requests) is available at sock 00079 additional_fd = sock; 00080 FD_SET(additional_fd, &all_fds); 00081 if (additional_fd > maxfd) { 00082 maxfd = additional_fd; 00083 } 00084 } 00085 00086 // Open UDP port 00087 if (netw_fd > 0) { 00088 // Port is already open, reuse it... 00089 FD_SET(netw_fd, &all_fds); 00090 00091 if (netw_fd> maxfd) { 00092 maxfd = netw_fd; 00093 } 00094 00095 return 0; 00096 } 00097 00098 sockaddr_in addr; 00099 netw_fd = socket(AF_INET, SOCK_DGRAM, 0); 00100 memset(&addr, 0, sizeof(addr)); 00101 addr.sin_family = AF_INET; 00102 00103 cModule* overlay = simulation.moduleByPath( 00104 "SingleHostNetwork.singleHost.overlay"); 00105 00106 if (overlay == NULL) { 00107 throw new cRuntimeError("UdpOutScheduler::initializeNetwork(): " 00108 "Overlay module not found!"); 00109 } 00110 00111 addr.sin_port = htons(overlay->gate("from_app")->toGate()-> 00112 ownerModule()->par("localPort").longValue()); 00113 00114 cModule* underlayConfigurator = 00115 simulation.moduleByPath("SingleHostNetwork.underlayConfigurator"); 00116 00117 if (underlayConfigurator == NULL) { 00118 throw new cRuntimeError("UdpOutScheduler::initializeNetwork(): " 00119 "UnderlayConfigurator module not found!"); 00120 } 00121 00122 if (strlen(underlayConfigurator->par("nodeIP").stringValue())) { 00123 addr.sin_addr.s_addr = htonl(IPAddress(underlayConfigurator-> 00124 par("nodeIP").stringValue()).getInt()); 00125 } else { 00126 addr.sin_addr.s_addr = htonl(INADDR_ANY); 00127 } 00128 00129 if (bind( netw_fd, (sockaddr*)&addr, sizeof(addr)) < 0) { 00130 opp_error("Error binding to UDP socket"); 00131 return -1; 00132 } 00133 00134 FD_SET(netw_fd, &all_fds); 00135 00136 if (netw_fd> maxfd) { 00137 maxfd = netw_fd; 00138 } 00139 00140 return 0; 00141 }
void UdpOutScheduler::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.
00143 { 00144 int new_sock = accept( additional_fd, 0, 0 ); 00145 00146 if (new_sock < 0) { 00147 opp_warning("Error connecting to remote app"); 00148 return; 00149 } 00150 00151 if (appConnectionLimit) { 00152 int count = 0; 00153 00154 for (int fd = 0; fd <= maxfd; fd++) { 00155 if (fd == netw_fd) continue; 00156 if (fd == additional_fd) continue; 00157 if (FD_ISSET(fd, &all_fds)) count++; 00158 } 00159 00160 if (count >= appConnectionLimit) { 00161 // We already have too many connections to external applications 00162 // "reject" connection 00163 close(new_sock); 00164 ev << "[UdpOutScheduler::additionalFD()]\n" 00165 << " Rejecting new app connection (FD: " << new_sock << ")" 00166 << endl; 00167 00168 return; 00169 } 00170 } 00171 00172 FD_SET(new_sock, &all_fds); 00173 00174 if (new_sock > maxfd) { 00175 maxfd = new_sock; 00176 } 00177 00178 // Inform app about new connection 00179 appPacketBuffer->push_back(PacketBufferEntry(0, 0, 00180 PacketBufferEntry::FD_NEW, new_sock)); 00181 00182 sendNotificationMsg(appNotificationMsg, appModule); 00183 00184 ev << "[UdpOutScheduler::additionalFD()]\n" 00185 << " Accepting new app connection (FD: " << new_sock << ")" 00186 << endl; 00187 }
char* UdpOutScheduler::dev [protected] |
Referenced by initializeNetwork(), and ~UdpOutScheduler().