Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
discard.c
Go to the documentation of this file.
00001 /** 00002 * @file discard.c 00003 * @brief Discard protocol 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @section Description 00026 * 00027 * The discard service is a useful debugging and measurement tool. The service 00028 * simply throws away any data it receives. Refer to RFC 863 for complete details 00029 * 00030 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00031 * @version 1.7.6 00032 **/ 00033 00034 //Switch to the appropriate trace level 00035 #define TRACE_LEVEL STD_SERVICES_TRACE_LEVEL 00036 00037 //Dependencies 00038 #include "core/net.h" 00039 #include "std_services/discard.h" 00040 #include "debug.h" 00041 00042 00043 /** 00044 * @brief Start TCP discard service 00045 * @return Error code 00046 **/ 00047 00048 error_t tcpDiscardStart(void) 00049 { 00050 error_t error; 00051 Socket *socket; 00052 OsTask *task; 00053 00054 //Debug message 00055 TRACE_INFO("Starting TCP discard service...\r\n"); 00056 00057 //Open a TCP socket 00058 socket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_IP_PROTO_TCP); 00059 //Failed to open socket? 00060 if(socket == NULL) 00061 return ERROR_OPEN_FAILED; 00062 00063 //Start of exception handling block 00064 do 00065 { 00066 //Bind the newly created socket to port 9 00067 error = socketBind(socket, &IP_ADDR_ANY, DISCARD_PORT); 00068 //Failed to bind the socket to the desired port? 00069 if(error) 00070 break; 00071 00072 //Place the socket into listening mode 00073 error = socketListen(socket, 0); 00074 //Any error to report? 00075 if(error) 00076 break; 00077 00078 //Create a task to handle incoming connection requests 00079 task = osCreateTask("TCP Discard Listener", tcpDiscardListenerTask, 00080 socket, DISCARD_SERVICE_STACK_SIZE, DISCARD_SERVICE_PRIORITY); 00081 00082 //Unable to create the task? 00083 if(task == OS_INVALID_HANDLE) 00084 { 00085 //Report an error to the calling function 00086 error = ERROR_OUT_OF_RESOURCES; 00087 break; 00088 } 00089 00090 //End of exception handling block 00091 } while(0); 00092 00093 //Any error to report? 00094 if(error) 00095 { 00096 //Clean up side effects... 00097 socketClose(socket); 00098 } 00099 00100 //Return status code 00101 return error; 00102 } 00103 00104 00105 /** 00106 * @brief Task handling connection requests 00107 * @param[in] param Pointer to the discard service context 00108 **/ 00109 00110 void tcpDiscardListenerTask(void *param) 00111 { 00112 error_t error; 00113 uint16_t clientPort; 00114 IpAddr clientIpAddr; 00115 Socket *serverSocket; 00116 Socket *clientSocket; 00117 DiscardServiceContext *context; 00118 OsTask *task; 00119 00120 //Point to the listening socket 00121 serverSocket = (Socket *) param; 00122 00123 //Main loop 00124 while(1) 00125 { 00126 //Accept an incoming connection 00127 clientSocket = socketAccept(serverSocket, &clientIpAddr, &clientPort); 00128 //Check whether a valid connection request has been received 00129 if(!clientSocket) continue; 00130 00131 //Debug message 00132 TRACE_INFO("Discard service: connection established with client %s port %" PRIu16 "\r\n", 00133 ipAddrToString(&clientIpAddr, NULL), clientPort); 00134 00135 //Adjust timeout 00136 error = socketSetTimeout(clientSocket, DISCARD_TIMEOUT); 00137 00138 //Any error to report? 00139 if(error) 00140 { 00141 //Close socket 00142 socketClose(clientSocket); 00143 //Wait for an incoming connection attempt 00144 continue; 00145 } 00146 00147 //Allocate resources for the new connection 00148 context = osAllocMem(sizeof(DiscardServiceContext)); 00149 00150 //Failed to allocate memory? 00151 if(context == NULL) 00152 { 00153 //Close socket 00154 socketClose(clientSocket); 00155 //Wait for an incoming connection attempt 00156 continue; 00157 } 00158 00159 //Record the handle of the newly created socket 00160 context->socket = clientSocket; 00161 00162 //Create a task to service the current connection 00163 task = osCreateTask("TCP Discard Connection", tcpDiscardConnectionTask, 00164 context, DISCARD_SERVICE_STACK_SIZE, DISCARD_SERVICE_PRIORITY); 00165 00166 //Did we encounter an error? 00167 if(task == OS_INVALID_HANDLE) 00168 { 00169 //Close socket 00170 socketClose(clientSocket); 00171 //Release resources 00172 osFreeMem(context); 00173 } 00174 } 00175 } 00176 00177 00178 /** 00179 * @brief TCP discard service implementation 00180 * @param[in] param Pointer to the discard service context 00181 **/ 00182 00183 void tcpDiscardConnectionTask(void *param) 00184 { 00185 error_t error; 00186 size_t n; 00187 size_t byteCount; 00188 systime_t startTime; 00189 systime_t duration; 00190 DiscardServiceContext *context; 00191 00192 //Get a pointer to the context 00193 context = (DiscardServiceContext *) param; 00194 //Get current time 00195 startTime = osGetSystemTime(); 00196 00197 //Total number of bytes received 00198 byteCount = 0; 00199 00200 //Main loop 00201 while(1) 00202 { 00203 //Throw away any received datagram... 00204 error = socketReceive(context->socket, context->buffer, DISCARD_BUFFER_SIZE, &n, 0); 00205 //Any error to report? 00206 if(error) 00207 break; 00208 00209 //Total number of bytes received 00210 byteCount += n; 00211 } 00212 00213 //Graceful shutdown 00214 socketShutdown(context->socket, SOCKET_SD_BOTH); 00215 //Compute total duration 00216 duration = osGetSystemTime() - startTime; 00217 //Avoid division by zero... 00218 if(!duration) duration = 1; 00219 00220 //Debug message 00221 TRACE_INFO("Discard service: %" PRIuSIZE " bytes " 00222 "received in %" PRIu32 " ms (%" PRIu32 " kBps, %" PRIu32 " kbps)\r\n", 00223 byteCount, duration, byteCount / duration, (byteCount * 8) / duration); 00224 00225 //Close socket 00226 socketClose(context->socket); 00227 //Release previously allocated memory 00228 osFreeMem(context); 00229 00230 //Kill ourselves 00231 osDeleteTask(NULL); 00232 } 00233 00234 00235 /** 00236 * @brief Start UDP discard service 00237 * @return Error code 00238 **/ 00239 00240 error_t udpDiscardStart(void) 00241 { 00242 error_t error; 00243 DiscardServiceContext *context; 00244 OsTask *task; 00245 00246 //Debug message 00247 TRACE_INFO("Starting UDP discard service...\r\n"); 00248 00249 //Allocate a memory block to hold the context 00250 context = osAllocMem(sizeof(DiscardServiceContext)); 00251 //Failed to allocate memory? 00252 if(context == NULL) 00253 return ERROR_OUT_OF_MEMORY; 00254 00255 //Start of exception handling block 00256 do 00257 { 00258 //Open a UDP socket 00259 context->socket = socketOpen(SOCKET_TYPE_DGRAM, SOCKET_IP_PROTO_UDP); 00260 00261 //Failed to open socket? 00262 if(!context->socket) 00263 { 00264 //Report an error 00265 error = ERROR_OPEN_FAILED; 00266 //Exit immediately 00267 break; 00268 } 00269 00270 //The server listens for incoming datagrams on port 9 00271 error = socketBind(context->socket, &IP_ADDR_ANY, DISCARD_PORT); 00272 //Unable to bind the socket to the desired port? 00273 if(error) 00274 break; 00275 00276 //Create a task to handle incoming datagrams 00277 task = osCreateTask("UDP Discard", udpDiscardTask, 00278 context, DISCARD_SERVICE_STACK_SIZE, DISCARD_SERVICE_PRIORITY); 00279 00280 //Unable to create the task? 00281 if(task == OS_INVALID_HANDLE) 00282 { 00283 //Report an error to the calling function 00284 error = ERROR_OUT_OF_RESOURCES; 00285 break; 00286 } 00287 00288 //End of exception handling block 00289 } while(0); 00290 00291 //Any error to report? 00292 if(error) 00293 { 00294 //Clean up side effects... 00295 socketClose(context->socket); 00296 osFreeMem(context); 00297 } 00298 00299 //Return status code 00300 return error; 00301 } 00302 00303 00304 /** 00305 * @brief UDP discard service implementation 00306 * @param[in] param Pointer to the discard service context 00307 **/ 00308 00309 void udpDiscardTask(void *param) 00310 { 00311 error_t error; 00312 size_t length; 00313 uint16_t port; 00314 IpAddr ipAddr; 00315 DiscardServiceContext *context; 00316 00317 //Get a pointer to the context 00318 context = (DiscardServiceContext *) param; 00319 00320 //Main loop 00321 while(1) 00322 { 00323 //Wait for an incoming datagram 00324 error = socketReceiveFrom(context->socket, &ipAddr, &port, 00325 context->buffer, DISCARD_BUFFER_SIZE, &length, 0); 00326 00327 //Any datagram received? 00328 if(!error) 00329 { 00330 //Debug message 00331 TRACE_INFO("Discard service: %" PRIuSIZE " bytes received from %s port %" PRIu16 "\r\n", 00332 length, ipAddrToString(&ipAddr, NULL), port); 00333 00334 //Throw away any received datagram... 00335 } 00336 } 00337 } 00338
Generated on Tue Jul 12 2022 17:10:13 by
