Skip to content

Commit

Permalink
Implement @{udp8} pattern in udp-server-h2client
Browse files Browse the repository at this point in the history
@{udp8} is used to get the last 8 characters in a
datagram received. It is useful for a given numeric
sequence, as represents a valid IPv4 address which
will be unique for that sequence.
  • Loading branch information
testillano authored and Eduardo Ramos Testillano (eramedu) committed Aug 7, 2023
1 parent d0428f3 commit e669487
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 19 deletions.
21 changes: 13 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1072,9 +1072,14 @@ Usage: udp-server-h2client [options]
Options:
UDP server will trigger one HTTP/2 request for every reception, replacing optionally
the '@{udp}' pattern on uri, headers and/or body provided, with the UDP data read.
If data received contains pipes (|), it is also possible to access each part during
parsing procedure through the use of pattern '@{udp.<n>}'.
certain patterns on uri, headers and/or body provided. Implemented patterns are the
following:
@{udp}: replaced by the whole UDP datagram received.
@{udp8}: selects the 8 least significant digits in the UDP datagram, and may
be used to build valid IPv4 addresses for a given sequence.
@{udp.<n>}: UDP datagram received may contain a pipe-separated list of tokens
and this pattern will be replaced by the nth one.
To stop the process you can send UDP message 'EOF'.
To print accumulated statistics you can send UDP message 'STATS' or stop/interrupt the process.
Expand Down Expand Up @@ -1141,7 +1146,7 @@ To print accumulated statistics you can send UDP message 'STATS' or stop/interru
This help.
Examples:
udp-server-h2client --udp-socket-path /tmp/udp.sock --print-each 1000 --timeout-milliseconds 1000 --uri http://0.0.0.0:8000/book/@{udp}
udp-server-h2client --udp-socket-path /tmp/udp.sock --print-each 1000 --timeout-milliseconds 1000 --uri http://0.0.0.0:8000/book/@{udp} --body "ipv4 is @{udp8}"
udp-server-h2client --udp-socket-path /tmp/udp.sock --print-each 1000 --method POST --uri http://0.0.0.0:8000/data --header "content-type:application/json" --body '{"book":"@{udp}"}'
To provide body from file, use this trick: --body "$(jq -c '.' long-body.json)"
Expand Down Expand Up @@ -1225,10 +1230,10 @@ Options:
Final value for datagram. Defaults to unlimited.
[--pattern <value>]
Pattern to be parsed by sequence (@{seq} is replaced by sequence). Defaults to '@{seq}'.
This parameter can occur multiple times to create a random set. For example, passing
'--pattern foo --pattern foo --pattern bar', there is a probability of 2/3 to select
'foo' and 1/3 to select 'bar'.
Pattern to build UDP datagram (reserved @{seq} is replaced by sequence number).
Defaults to '@{seq}'. This parameter can occur multiple times to create a random
set. For example, passing '--pattern foo --pattern foo --pattern bar', there is a
probability of 2/3 to select 'foo' and 1/3 to select 'bar'.
[-e|--print-each <value>]
Print messages each specific amount (must be positive). Defaults to 1.
Expand Down
13 changes: 8 additions & 5 deletions tools/udp-client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ void usage(int rc, const std::string &errorMessage = "")
<< " Final value for datagram. Defaults to unlimited.\n\n"

<< "[--pattern <value>]\n"
<< " Pattern to be parsed by sequence (@{seq} is replaced by sequence). Defaults to '@{seq}'.\n"
<< " This parameter can occur multiple times to create a random set. For example, passing\n"
<< " '--pattern foo --pattern foo --pattern bar', there is a probability of 2/3 to select\n"
<< " 'foo' and 1/3 to select 'bar'.\n\n"
<< " Pattern to build UDP datagram (reserved @{seq} is replaced by sequence number).\n"
<< " Defaults to '@{seq}'. This parameter can occur multiple times to create a random\n"
<< " set. For example, passing '--pattern foo --pattern foo --pattern bar', there is a\n"
<< " probability of 2/3 to select 'foo' and 1/3 to select 'bar'.\n\n"

<< "[-e|--print-each <value>]\n"
<< " Print messages each specific amount (must be positive). Defaults to 1.\n\n"
Expand Down Expand Up @@ -290,12 +290,13 @@ int main(int argc, char* argv[])
std::string udpDataSeq{}, udpData{};
std::string::size_type pos = 0u;
std::string from = "@{seq}";
long long int periodNS = (long long int)(1000000000.0/eps);

unsigned long long int sequence{};
auto startTimeNS = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch());
int patternsSize = patterns.size();

// Period:
long long int periodNS = (long long int)(1000000000.0/eps);
while (true) {

udpDataSeq = std::to_string(initialValue + sequence);
Expand Down Expand Up @@ -336,10 +337,12 @@ int main(int argc, char* argv[])
if (eps > 0) {
auto futureTimeNS = startTimeNS + std::chrono::nanoseconds(periodNS * sequence);
auto elapsedNS = std::chrono::duration_cast<std::chrono::nanoseconds>(futureTimeNS - std::chrono::system_clock::now().time_since_epoch());

std::this_thread::sleep_for(std::chrono::nanoseconds(elapsedNS));
}
}

// Wrapup
close(Sockfd);

exit(EXIT_SUCCESS);
Expand Down
31 changes: 25 additions & 6 deletions tools/udp-server-h2client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,14 @@ void usage(int rc, const std::string &errorMessage = "")
ss << "Usage: " << progname << " [options]\n\nOptions:\n\n"

<< "UDP server will trigger one HTTP/2 request for every reception, replacing optionally\n"
<< "the '@{udp}' pattern on uri, headers and/or body provided, with the UDP data read.\n"
<< "If data received contains pipes (|), it is also possible to access each part during\n"
<< "parsing procedure through the use of pattern '@{udp.<n>}'.\n"
<< "certain patterns on uri, headers and/or body provided. Implemented patterns are the\n"
<< "following:\n"
<< '\n'
<< " @{udp}: replaced by the whole UDP datagram received.\n"
<< " @{udp8}: selects the 8 least significant digits in the UDP datagram, and may\n"
<< " be used to build valid IPv4 addresses for a given sequence.\n"
<< " @{udp.<n>}: UDP datagram received may contain a pipe-separated list of tokens\n"
<< " and this pattern will be replaced by the nth one.\n"
<< "\n"
<< "To stop the process you can send UDP message 'EOF'.\n"
<< "To print accumulated statistics you can send UDP message 'STATS' or stop/interrupt the process.\n\n"
Expand Down Expand Up @@ -171,7 +176,7 @@ void usage(int rc, const std::string &errorMessage = "")
<< " This help.\n\n"

<< "Examples: " << '\n'
<< " " << progname << " --udp-socket-path /tmp/udp.sock --print-each 1000 --timeout-milliseconds 1000 --uri http://0.0.0.0:8000/book/@{udp}" << '\n'
<< " " << progname << " --udp-socket-path /tmp/udp.sock --print-each 1000 --timeout-milliseconds 1000 --uri http://0.0.0.0:8000/book/@{udp} --body \"ipv4 is @{udp8}\"" << '\n'
<< " " << progname << " --udp-socket-path /tmp/udp.sock --print-each 1000 --method POST --uri http://0.0.0.0:8000/data --header \"content-type:application/json\" --body '{\"book\":\"@{udp}\"}'" << '\n'
<< '\n'
<< " To provide body from file, use this trick: --body \"$(jq -c '.' long-body.json)\"" << '\n'
Expand Down Expand Up @@ -308,6 +313,13 @@ void replaceVariables(std::string &str, const std::map<std::string, std::string>
}
}

// Extract least N significant characters from string:
std::string extractLastNChars(const std::string &input, int n) {
if(input.size() < n) return input;
return input.substr(input.size() - n);
}


// Transform input in the form "<double>,<double>,..,<double>" to bucket boundaries vector
// Cientific notation is allowed, for example boundary for 150us would be 150e-6
// Returns the final string ignoring non-double values scanned. Also sort is applied.
Expand Down Expand Up @@ -366,11 +378,15 @@ class Stream {
headers_ = headers;
timeout_ms_ = millisecondsTimeout;

// Main variable @{udp}, and possible parts:
// Main variable @{udp}
std::string mainVar = "udp";
variables_[mainVar] = data_;

// check pipes:
// Reserved variables:
// @{udp8}
variables_["udp8"] = extractLastNChars(data_, 8);

// Variable parts: @{udp.1}, @{udp.2{, etc.
char delimiter = '|';
if (data_.find(delimiter) == std::string::npos)
return;
Expand Down Expand Up @@ -856,6 +872,9 @@ int main(int argc, char* argv[])
}
}

// Join workers:
for (auto &w: myWorkers) w.join();

// wrap up
wrapup();

Expand Down

0 comments on commit e669487

Please sign in to comment.