udpoutscheduler.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 "udpoutscheduler.h"
00025 #include "IPvXAddress.h"
00026 #include <regmacros.h>
00027
00028 Register_Class(UdpOutScheduler);
00029
00030
00031 extern cConfigOption *CFGID_EXTERNALAPP_APP_PORT;
00032
00033 UdpOutScheduler::~UdpOutScheduler()
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 UdpOutScheduler::initializeNetwork()
00045 {
00046
00047 int appPort = ev.getConfig()->getAsInt(CFGID_EXTERNALAPP_APP_PORT, 0);
00048
00049
00050 if (appPort > 0) {
00051
00052 struct sockaddr_in server;
00053 SOCKET sock;
00054
00055
00056 sock = socket(AF_INET, SOCK_STREAM, 0);
00057
00058 if (sock == INVALID_SOCKET) {
00059 opp_error("Error creating socket");
00060 return -1;
00061 }
00062
00063 int on = 1;
00064 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&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
00076 if (listen( sock, 5 ) == -1) {
00077 opp_error("Error listening on app socket");
00078 return -1;
00079 }
00080
00081
00082 additional_fd = sock;
00083 FD_SET(additional_fd, &all_fds);
00084 if (additional_fd > maxfd) {
00085 maxfd = additional_fd;
00086 }
00087 }
00088
00089
00090 if (netw_fd != INVALID_SOCKET) {
00091
00092 FD_SET(netw_fd, &all_fds);
00093
00094 if (netw_fd> maxfd) {
00095 maxfd = netw_fd;
00096 }
00097
00098 return 0;
00099 }
00100
00101 sockaddr_in addr;
00102 netw_fd = socket(AF_INET, SOCK_DGRAM, 0);
00103 memset(&addr, 0, sizeof(addr));
00104 addr.sin_family = AF_INET;
00105
00106 cModule* overlay = simulation.getModuleByPath(
00107 "SingleHostUnderlayNetwork.overlayTerminal[0].overlay");
00108
00109 if (overlay == NULL) {
00110 throw cRuntimeError("UdpOutScheduler::initializeNetwork(): "
00111 "Overlay module not found!");
00112 }
00113
00114 addr.sin_port = htons(overlay->gate("appIn")->getNextGate()->
00115 getOwnerModule()->par("localPort").longValue());
00116
00117 cModule* underlayConfigurator =
00118 simulation.getModuleByPath("SingleHostUnderlayNetwork.underlayConfigurator");
00119
00120 if (underlayConfigurator == NULL) {
00121 throw cRuntimeError("UdpOutScheduler::initializeNetwork(): "
00122 "UnderlayConfigurator module not found!");
00123 }
00124
00125 if (strlen(underlayConfigurator->par("nodeIP").stringValue())) {
00126 addr.sin_addr.s_addr = htonl(IPAddress(underlayConfigurator->
00127 par("nodeIP").stringValue()).getInt());
00128 } else {
00129 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00130 }
00131
00132 if (bind( netw_fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
00133 opp_error("Error binding to UDP socket");
00134 return -1;
00135 }
00136
00137 FD_SET(netw_fd, &all_fds);
00138
00139 if (netw_fd> maxfd) {
00140 maxfd = netw_fd;
00141 }
00142
00143 return 0;
00144 }
00145
00146 void UdpOutScheduler::additionalFD() {
00147 sockaddr* from = (sockaddr*) new sockaddr_in;
00148 socklen_t addrlen = sizeof(sockaddr_in);
00149
00150 SOCKET new_sock = accept( additional_fd, from, &addrlen );
00151
00152 if (new_sock == INVALID_SOCKET) {
00153 opp_warning("Error connecting to remote app");
00154 return;
00155 }
00156
00157 if (appConnectionLimit) {
00158 int count = 0;
00159
00160 for (SOCKET fd = 0; fd <= maxfd; fd++) {
00161 if (fd == netw_fd) continue;
00162 if (fd == additional_fd) continue;
00163 if (FD_ISSET(fd, &all_fds)) count++;
00164 }
00165
00166 if (count >= appConnectionLimit) {
00167
00168
00169 #ifdef _WIN32
00170 closesocket(new_sock);
00171 #else
00172 close(new_sock);
00173 #endif
00174 ev << "[UdpOutScheduler::additionalFD()]\n"
00175 << " Rejecting new app connection (FD: " << new_sock << ")"
00176 << endl;
00177
00178 return;
00179 }
00180 }
00181
00182 FD_SET(new_sock, &all_fds);
00183
00184 if (new_sock > maxfd) {
00185 maxfd = new_sock;
00186 }
00187
00188
00189 appPacketBuffer->push_back(PacketBufferEntry(0, 0, from, addrlen,
00190 PacketBufferEntry::PACKET_FD_NEW, new_sock));
00191
00192 sendNotificationMsg(appNotificationMsg, appModule);
00193
00194 ev << "[UdpOutScheduler::additionalFD()]\n"
00195 << " Accepting new app connection (FD: " << new_sock << ")"
00196 << endl;
00197 }