Merge remote-tracking branch 'upstream/master' into master-to-security
This commit is contained in:
		
						commit
						67c49235db
					
				
					 110 changed files with 2714 additions and 4540 deletions
				
			
		| 
						 | 
				
			
			@ -1749,7 +1749,7 @@ static void set_mode_ping (int *xoptind, int xargc, char * const xargv[])
 | 
			
		|||
  {
 | 
			
		||||
    int pos = 0, mult = 1;
 | 
			
		||||
    double ping_rate;
 | 
			
		||||
    if (strcmp (xargv[*xoptind], "inf") == 0 && lookup_multiplier (frequency_units, xargv[*xoptind] + 3) > 0)
 | 
			
		||||
    if (strncmp (xargv[*xoptind], "inf", 3) == 0 && lookup_multiplier (frequency_units, xargv[*xoptind] + 3) > 0)
 | 
			
		||||
    {
 | 
			
		||||
      ping_intv = 0;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1891,16 +1891,16 @@ int main (int argc, char *argv[])
 | 
			
		|||
 | 
			
		||||
  while ((opt = getopt (argc, argv, "cd:D:i:n:k:uLK:T:Q:R:h")) != EOF)
 | 
			
		||||
  {
 | 
			
		||||
    int pos;
 | 
			
		||||
    switch (opt)
 | 
			
		||||
    {
 | 
			
		||||
      case 'c': collect_stats = true; break;
 | 
			
		||||
      case 'd': {
 | 
			
		||||
        char *col;
 | 
			
		||||
        int pos;
 | 
			
		||||
        (void) ddsrt_strlcpy (netload_if, optarg, sizeof (netload_if));
 | 
			
		||||
        if ((col = strrchr (netload_if, ':')) == NULL || col == netload_if ||
 | 
			
		||||
            (sscanf (col+1, "%lf%n", &netload_bw, &pos) != 1 || (col+1)[pos] != 0))
 | 
			
		||||
          error3 ("-d%s: expected DEVICE:BANDWIDTH\n", optarg);
 | 
			
		||||
          error3 ("-d %s: expected DEVICE:BANDWIDTH\n", optarg);
 | 
			
		||||
        *col = 0;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -1917,10 +1917,9 @@ int main (int argc, char *argv[])
 | 
			
		|||
        else if (strcmp (optarg, "OU") == 0) topicsel = OU;
 | 
			
		||||
        else if (strcmp (optarg, "UK16") == 0) topicsel = UK16;
 | 
			
		||||
        else if (strcmp (optarg, "UK1024") == 0) topicsel = UK1024;
 | 
			
		||||
        else error3 ("%s: unknown topic\n", optarg);
 | 
			
		||||
        else error3 ("-T %s: unknown topic\n", optarg);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'Q': {
 | 
			
		||||
        int pos;
 | 
			
		||||
        double d;
 | 
			
		||||
        unsigned long n;
 | 
			
		||||
        if (sscanf (optarg, "rss:%lf%n", &d, &pos) == 1 && (optarg[pos] == 0 || optarg[pos] == '%')) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1935,11 +1934,16 @@ int main (int argc, char *argv[])
 | 
			
		|||
        } else if (sscanf (optarg, "minmatch:%lu%n", &n, &pos) == 1 && optarg[pos] == 0) {
 | 
			
		||||
          minmatch = (uint32_t) n;
 | 
			
		||||
        } else {
 | 
			
		||||
          error3 ("-Q%s: invalid success criterium\n", optarg);
 | 
			
		||||
          error3 ("-Q %s: invalid success criterium\n", optarg);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'R': tref = 0; sscanf (optarg, "%"SCNd64, &tref); break;
 | 
			
		||||
      case 'R': {
 | 
			
		||||
        tref = 0;
 | 
			
		||||
        if (sscanf (optarg, "%"SCNd64"%n", &tref, &pos) != 1 || optarg[pos] != 0)
 | 
			
		||||
          error3 ("-R %s: invalid reference time\n", optarg);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'h': default: usage (); break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1959,7 +1963,7 @@ int main (int argc, char *argv[])
 | 
			
		|||
  if (nkeyvals == 0)
 | 
			
		||||
    nkeyvals = 1;
 | 
			
		||||
  if (topicsel == OU && nkeyvals != 1)
 | 
			
		||||
    error3 ("-n%u invalid: topic OU has no key\n", nkeyvals);
 | 
			
		||||
    error3 ("-n %u invalid: topic OU has no key\n", nkeyvals);
 | 
			
		||||
  if (topicsel != KS && baggagesize != 0)
 | 
			
		||||
    error3 ("size %"PRIu32" invalid: only topic KS has a sequence\n", baggagesize);
 | 
			
		||||
  if (baggagesize != 0 && baggagesize < 12)
 | 
			
		||||
| 
						 | 
				
			
			@ -2047,8 +2051,15 @@ int main (int argc, char *argv[])
 | 
			
		|||
     has convenience functions for that ...) */
 | 
			
		||||
  if ((rd_participants = dds_create_reader (dp, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL)) < 0)
 | 
			
		||||
    error2 ("dds_create_reader(participants) failed: %d\n", (int) rd_participants);
 | 
			
		||||
  /* set listener later: DATA_AVAILABLE still has the nasty habit of potentially triggering
 | 
			
		||||
     before the reader is accessible to the application via its handle */
 | 
			
		||||
  if ((rd_subscriptions = dds_create_reader (dp, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL)) < 0)
 | 
			
		||||
    error2 ("dds_create_reader(subscriptions) failed: %d\n", (int) rd_subscriptions);
 | 
			
		||||
  if ((rd_publications = dds_create_reader (dp, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL)) < 0)
 | 
			
		||||
    error2 ("dds_create_reader(publications) failed: %d\n", (int) rd_publications);
 | 
			
		||||
 | 
			
		||||
  /* Set DATA_AVAILABLE listener on participant later: it has the nasty habit of potentially
 | 
			
		||||
     triggering before the reader is accessible to the application via its handle. Furthermore,
 | 
			
		||||
     upon matching a participant, a new writer is created that gets a publication_matched
 | 
			
		||||
     listener, which in turn depends on rd_subscriptions. */
 | 
			
		||||
  listener = dds_create_listener (NULL);
 | 
			
		||||
  dds_lset_data_available (listener, participant_data_listener);
 | 
			
		||||
  dds_set_listener (rd_participants, listener);
 | 
			
		||||
| 
						 | 
				
			
			@ -2056,10 +2067,6 @@ int main (int argc, char *argv[])
 | 
			
		|||
  /* then there is the matter of data arriving prior to setting the listener ... this state
 | 
			
		||||
     of affairs is undoubtedly a bug */
 | 
			
		||||
  participant_data_listener (rd_participants, NULL);
 | 
			
		||||
  if ((rd_subscriptions = dds_create_reader (dp, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL)) < 0)
 | 
			
		||||
    error2 ("dds_create_reader(subscriptions) failed: %d\n", (int) rd_subscriptions);
 | 
			
		||||
  if ((rd_publications = dds_create_reader (dp, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL)) < 0)
 | 
			
		||||
    error2 ("dds_create_reader(publications) failed: %d\n", (int) rd_publications);
 | 
			
		||||
 | 
			
		||||
  /* stats writer always exists, reader only when we were requested to collect & print stats */
 | 
			
		||||
  qos = dds_create_qos ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ my $last_infots;
 | 
			
		|||
my %spdp_info;
 | 
			
		||||
my $hexmode = 1;
 | 
			
		||||
my $sysid_hex;
 | 
			
		||||
my $proto = '(?:udp4?|tcp4?)\/';
 | 
			
		||||
my $proto_ip = "(?:(?:udp[46]?|tcp[46]?)\/)?(?:[0-9.]+|\[[0-9a-fA-F:]+\])";
 | 
			
		||||
my %tstamps;
 | 
			
		||||
my %topic_qos;
 | 
			
		||||
my $recv_packet = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -275,12 +275,14 @@ while(<>) {
 | 
			
		|||
    check_disccomplete("B", $1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  # Special handling of INFOTS & SPDP for extracting start times of remote nodes and making an
 | 
			
		||||
  # informed guess as to whether the remote node learned of our existence because we sent a
 | 
			
		||||
  # multicast or a unicast
 | 
			
		||||
  if (/recv(?:UC|MC)?: INFOTS\((\d+)\.(\d+)\)/) {
 | 
			
		||||
    # Special handling of INFOTS for guessing at source time stamps (in particular also
 | 
			
		||||
    # for guessing at start times of other nodes
 | 
			
		||||
    $last_infots = ($1 - $t0sec) + ($2/1e3 - $t0usec) / 1e6;
 | 
			
		||||
  } elsif ($hexmode ? m/recv: DATA\(((?:[0-9a-f]+:){3}100c2) -> ($guidre)/ : m/recv: DATA\(((?:[0-9a-f]+:){3}65730) -> ($guidre)/) {
 | 
			
		||||
  } elsif ($hexmode ? m/recv(?:UC|MC)?: DATA\(((?:[0-9a-f]+:){3}100c2) -> ($guidre)/ : m/recv(?:UC|MC)?: DATA\(((?:[0-9a-f]+:){3}65730) -> ($guidre)/) {
 | 
			
		||||
    # SPDP for extracting start times of remote nodes and making an informed guess as to
 | 
			
		||||
    # whether the remote node learned of our existence because we sent a multicast or a
 | 
			
		||||
    # unicast
 | 
			
		||||
    my $src = $1; my $dst = $2;
 | 
			
		||||
    (my $ppguid = hexify($src)) =~ s/:(100c2|65730)$/:1c1/;
 | 
			
		||||
    my $directed = ($dst !~ /^0:0:0:/);
 | 
			
		||||
| 
						 | 
				
			
			@ -290,23 +292,39 @@ while(<>) {
 | 
			
		|||
      # relatively long after discovery.  "Relatively long" being a pretty difficult
 | 
			
		||||
      # concept to work with, we use the "discovery complete" flag to see if it is a
 | 
			
		||||
      # likely asymmetrical disconnect
 | 
			
		||||
      if ($proxypp{$ppguid}->{disccompleteflag}) {
 | 
			
		||||
      if ($proxypp{$ppguid}->{disccompleteflag} && $ts > $proxypp{$ppguid}->{tasymdisc} + 5) {
 | 
			
		||||
        my $sysid = $proxypp{$ppguid}->{sysid};
 | 
			
		||||
        my $sx = decimal_sysid($sysid);
 | 
			
		||||
        printf "%9.3f %35s $topfmt ASYM %s (%s; %s; %s) likely asymmetrical disconnect\n", $ts, $sysid, "", $sysid{$sysid}->{ip}, $sx, $sysid{$sysid}->{name}, vendorstr($spdp_info{$ppguid}->{vendor});
 | 
			
		||||
        $proxypp{$ppguid}->{tasymdisc} = $ts;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } elsif (/: ACKNACK\(#\d+:1\/0:\s+(?:$leasere)?([0-9a-f]+(?::[0-9a-f]+){2}:([34])c7) -\>/) {
 | 
			
		||||
    # An ACKNACK that acks nothing, nacks nothing and requests a response (no "F" flag
 | 
			
		||||
    # present) is a tell-tale sign of a pre-emptive ACKNACK.  Receipt of one of those
 | 
			
		||||
    # after having received a normal one is indicative of an asymmetrical disconnect.
 | 
			
		||||
    # Detecting when all is well again is too hard.  Being lazy, we simply gate it with
 | 
			
		||||
    # the "discovery complete" flag and suppress it within a window of 1s.
 | 
			
		||||
    my $src = $1; my $src_id = $2;
 | 
			
		||||
    (my $ppguid = hexify($src)) =~ s/:[0-9a-f]+$/:1c1/;
 | 
			
		||||
    if (exists $proxypp{$ppguid} && $proxypp{$ppguid}->{disccompleteflag} && $ts > $proxypp{$ppguid}->{tasymdisc} + 1) {
 | 
			
		||||
      my $sysid = $proxypp{$ppguid}->{sysid};
 | 
			
		||||
      my $sx = decimal_sysid($sysid);
 | 
			
		||||
      printf "%9.3f %35s $topfmt ASYM %s (%s; %s; %s) likely asymmetrical disconnect\n", $ts, $sysid, "", $sysid{$sysid}->{ip}, $sx, $sysid{$sysid}->{name}, vendorstr($spdp_info{$ppguid}->{vendor});
 | 
			
		||||
      $proxypp{$ppguid}->{tasymdisc} = $ts;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (/: ownip: (?:$proto)?([0-9.]+)/o) {
 | 
			
		||||
  if (/: ownip: ($proto_ip)/o) {
 | 
			
		||||
    $ownip = $1;
 | 
			
		||||
    $ownip =~ s/^(udp|tcp)[46]?\///;
 | 
			
		||||
  } elsif (/: PARTICIPANT ($guidre) QOS=\{/o) {
 | 
			
		||||
    my $guid = hexify($1);
 | 
			
		||||
    (my $gid = $guid) =~ s/:[^:]+$//;
 | 
			
		||||
    my $userdata = $_;
 | 
			
		||||
    if ($userdata =~ s/.*QOS=\{.*?user_data=//) {
 | 
			
		||||
      $userdata =~ s/\}$//;
 | 
			
		||||
      $userdata =~ s/,entity_factory=\d$//;
 | 
			
		||||
      $userdata =~ s/,(?:(?:prismtech|adlink)_)?entity_factory=\d$//;
 | 
			
		||||
      $userdata = " userdata:$userdata";
 | 
			
		||||
    } else {
 | 
			
		||||
      $userdata = "";
 | 
			
		||||
| 
						 | 
				
			
			@ -320,7 +338,7 @@ while(<>) {
 | 
			
		|||
    }
 | 
			
		||||
    $pp{$guid} = { gid => $gid, guid => $guid, name => $name, sname => $sname, sub => {}, pub => {} };
 | 
			
		||||
    if (! $self_seen) {
 | 
			
		||||
      my $sysid = $guid;
 | 
			
		||||
      (my $sysid = $guid) =~ s/:1c1$//;
 | 
			
		||||
      $self_seen = 1;
 | 
			
		||||
      $sysid{$sysid} = { self => 1, ip => $ownip, name => $name, sname => $sname };
 | 
			
		||||
      my $sx = decimal_sysid($sysid);
 | 
			
		||||
| 
						 | 
				
			
			@ -352,7 +370,9 @@ while(<>) {
 | 
			
		|||
    $rwguid{$tid} = $guid; # if $is_cyclone;
 | 
			
		||||
    die "$guid $rwguid{$tid}" unless $guid eq $rwguid{$tid};
 | 
			
		||||
    my $topic; my $type; my $groupcoh; my $partitions; my $keepall;
 | 
			
		||||
    if ($qos =~ /topic(?:_name)?=([^,]+?),type(?:_name)=([^,]+?).*?,partition=\{([^}]*?)\}/) {
 | 
			
		||||
    # GUID prefix of 0:0:0: local built-in writer
 | 
			
		||||
    my $local_builtin = ($guid =~ /^0:0:0:/);
 | 
			
		||||
    if (! $local_builtin && $qos =~ /topic(?:_name)?="?([^,"]+?)"?,type(?:_name)="?([^,"]+?)"?.*?,partition=\{([^}]*?)\}/) {
 | 
			
		||||
      $topic = $1; $type = $2; $partitions = $3;
 | 
			
		||||
      die unless $qos =~ /,history=([01]):/; $keepall = $1;
 | 
			
		||||
      die unless $qos =~ /,presentation=(\d:\d):\d/; $groupcoh = ($1 eq "2:1");
 | 
			
		||||
| 
						 | 
				
			
			@ -361,7 +381,7 @@ while(<>) {
 | 
			
		|||
      }
 | 
			
		||||
      $rwgid{$tid} = $psguid{$tid} = $psgid{$tid} = "" if 1; # $is_cyclone;
 | 
			
		||||
    } else {
 | 
			
		||||
      # no topic, type: DDSI built-in reader/writer
 | 
			
		||||
      # all-zero GUID prefix or no topic, type: DDSI built-in reader/writer
 | 
			
		||||
      if (defined $rwgid{$tid} || $ftrflag{$tid}) {
 | 
			
		||||
        die;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -449,43 +469,46 @@ while(<>) {
 | 
			
		|||
      die;
 | 
			
		||||
    }
 | 
			
		||||
    if (!defined ($wr{$wrguid}->{topic})) {
 | 
			
		||||
      die;
 | 
			
		||||
    }
 | 
			
		||||
    my $wr = $wr{$wrguid};
 | 
			
		||||
    $cseq = "C#$cseq" if $cseq ne "";
 | 
			
		||||
    my $dest = getdest($wrguid);
 | 
			
		||||
    $wr->{seq} = $seq;
 | 
			
		||||
    if (defined $wr->{cs}) {
 | 
			
		||||
      $wr->{cs}->{seq} = $seq unless defined $wr->{cs}->{seq};
 | 
			
		||||
    }
 | 
			
		||||
    if (scalar (keys %{$wr->{matches}}) > 0) {
 | 
			
		||||
      push @ackcheck, { ts => $ts + 1, tswrite => $ts, wrguid => $wrguid, seq => $seq };
 | 
			
		||||
    }
 | 
			
		||||
    my $op = ($data =~ /^:e:/) ? "W  " : $opstr{$st.$dflag};
 | 
			
		||||
    my $print = 0;
 | 
			
		||||
    my $printlim = $shows{limit};
 | 
			
		||||
    $xmit_appdata++;
 | 
			
		||||
    $print = show_topic($wr->{topic}) && $shows{out};
 | 
			
		||||
    $print = 0 unless $data =~ /$data_filter/o;
 | 
			
		||||
    my $sdata = $printlim ? (sprintf "%-100.100s", $data) : (sprintf "%-100s", $data);
 | 
			
		||||
    printf "%9.3f %35s $topfmt %s #%-4d %-6s XMT  %s -> %s\n", $ts, fmtguid($wrguid), $wr->{stopic}, $op, $seq, $cseq, $sdata, $dest if $print;
 | 
			
		||||
    if ($data =~ /^:e:/ && defined $wr->{cs}) {
 | 
			
		||||
      # assume empty transaction if no $wr->{cs}
 | 
			
		||||
      my $pub = $pub{$wr->{psguid}};
 | 
			
		||||
      die unless defined $pub;
 | 
			
		||||
      $wr->{cs} = undef;
 | 
			
		||||
      if ($pub->{txn} == 0) {
 | 
			
		||||
        # presumably an empty transaction
 | 
			
		||||
        $pub->{txn} = keys %{$pub->{es}};
 | 
			
		||||
        printf "%9.3f %35s $topfmt %16s XMT  BEGIN [empty, %d writers]\n", $ts, fmtguid($pub->{guid}), "", "", $pub->{txn} if $shows{out};
 | 
			
		||||
      # PMD looks like regular data but is built-in without a topic name
 | 
			
		||||
      die unless $wrguid =~ /[4c][23]$/;
 | 
			
		||||
    } else {
 | 
			
		||||
      my $wr = $wr{$wrguid};
 | 
			
		||||
      $cseq = "C#$cseq" if $cseq ne "";
 | 
			
		||||
      my $dest = getdest($wrguid);
 | 
			
		||||
      $wr->{seq} = $seq;
 | 
			
		||||
      if (defined $wr->{cs}) {
 | 
			
		||||
        $wr->{cs}->{seq} = $seq unless defined $wr->{cs}->{seq};
 | 
			
		||||
      }
 | 
			
		||||
      if (--$pub->{txn} == 0) {
 | 
			
		||||
        printf "%9.3f %35s $topfmt %16s XMT  COMMIT\n", $ts, fmtguid($pub->{guid}), "", ""
 | 
			
		||||
          if $shows{out};
 | 
			
		||||
      if (scalar (keys %{$wr->{matches}}) > 0) {
 | 
			
		||||
        push @ackcheck, { ts => $ts + 1, tswrite => $ts, wrguid => $wrguid, seq => $seq };
 | 
			
		||||
      }
 | 
			
		||||
      my $op = ($data =~ /^:e:/) ? "W  " : $opstr{$st.$dflag};
 | 
			
		||||
      my $print = 0;
 | 
			
		||||
      my $printlim = $shows{limit};
 | 
			
		||||
      $xmit_appdata++;
 | 
			
		||||
      $print = show_topic($wr->{topic}) && $shows{out};
 | 
			
		||||
      $print = 0 unless $data =~ /$data_filter/o;
 | 
			
		||||
      my $sdata = $printlim ? (sprintf "%-100.100s", $data) : (sprintf "%-100s", $data);
 | 
			
		||||
      printf "%9.3f %35s $topfmt %s #%-4d %-6s XMT  %s -> %s\n", $ts, fmtguid($wrguid), $wr->{stopic}, $op, $seq, $cseq, $sdata, $dest if $print;
 | 
			
		||||
      if ($data =~ /^:e:/ && defined $wr->{cs}) {
 | 
			
		||||
        # assume empty transaction if no $wr->{cs}
 | 
			
		||||
        my $pub = $pub{$wr->{psguid}};
 | 
			
		||||
        die unless defined $pub;
 | 
			
		||||
        $wr->{cs} = undef;
 | 
			
		||||
        if ($pub->{txn} == 0) {
 | 
			
		||||
          # presumably an empty transaction
 | 
			
		||||
          $pub->{txn} = keys %{$pub->{es}};
 | 
			
		||||
          printf "%9.3f %35s $topfmt %16s XMT  BEGIN [empty, %d writers]\n", $ts, fmtguid($pub->{guid}), "", "", $pub->{txn} if $shows{out};
 | 
			
		||||
        }
 | 
			
		||||
        if (--$pub->{txn} == 0) {
 | 
			
		||||
          printf "%9.3f %35s $topfmt %16s XMT  COMMIT\n", $ts, fmtguid($pub->{guid}), "", ""
 | 
			
		||||
            if $shows{out};
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } elsif (/: (?:SPDP ST\d+)?SPDP ST(\d) ($guidre)\s+bes\s+([0-9a-f]+)\s+.*NEW(?: processguid ($guidre) )?.*?meta(?: (?:$proto)?[0-9.]+:\d+)*? (?:$proto)?([0-9.]+:\d+)\)/o) {
 | 
			
		||||
  } elsif (/: (?:SPDP ST\d+)?SPDP ST(\d) ($guidre)\s+bes\s+([0-9a-f]+)\s+.*NEW(?: processguid ($guidre) )?.*?meta(?: ${proto_ip}:\d+)*? (${proto_ip}:\d+)\)/o) {
 | 
			
		||||
    my $st = $1; my $ppguid = hexify($2); my $bes = hex $3; my $processguid = $4; my $ip = $5;
 | 
			
		||||
    $ip =~ s/^(udp|tcp)[46]?\///;
 | 
			
		||||
    my $hostname = $ip;
 | 
			
		||||
    my $sysid;
 | 
			
		||||
    if (defined $processguid) {
 | 
			
		||||
| 
						 | 
				
			
			@ -499,8 +522,9 @@ while(<>) {
 | 
			
		|||
        # presumably OSPL: first word is system id
 | 
			
		||||
        ($sysid = $ppguid) =~ s/:.*//;
 | 
			
		||||
      } else {
 | 
			
		||||
        # presumably Cyclone, old format: 2nd word is process id
 | 
			
		||||
        ($sysid = $ppguid) =~ s/:[0-9a-f]+:1c1$//;
 | 
			
		||||
        # presumably Cyclone, old format: 2nd word is process id; new format: altogether
 | 
			
		||||
        # crazy -- so don't bother with the old one
 | 
			
		||||
        ($sysid = $ppguid) =~ s/:1c1$//;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      ($sysid = $ppguid) =~ s/:1c1$//;
 | 
			
		||||
| 
						 | 
				
			
			@ -562,6 +586,7 @@ while(<>) {
 | 
			
		|||
            sname => $sname,
 | 
			
		||||
            infots => $spdp_info{$ppguid}->{ts},
 | 
			
		||||
            tcreate => $ts,
 | 
			
		||||
            tasymdisc => $ts,
 | 
			
		||||
            non_spdp_seen => 0,
 | 
			
		||||
            disccomplete => init_proxypp_disccomplete($bes),
 | 
			
		||||
            disccompleteflag => 0,
 | 
			
		||||
| 
						 | 
				
			
			@ -625,7 +650,7 @@ while(<>) {
 | 
			
		|||
    my $h = ($kind eq "READER") ? \%prd : \%pwr;
 | 
			
		||||
    my $hk = ($kind eq "READER") ? "prd" : "pwr";
 | 
			
		||||
    my $qos = $3;
 | 
			
		||||
    unless ($3 =~ /topic(?:_name)?=([^,]+?),type(?:_name)?=([^,]+?),(?:.+?,)?partition=\{([^}]*?)\}/) {
 | 
			
		||||
    unless ($qos =~ /topic(?:_name)?="?([^,"]+?)"?,type(?:_name)?="?([^,"]+?)"?,(?:.+?,)?partition=\{([^}]*?)\}/) {
 | 
			
		||||
      die unless $prwguid =~ /[4c][27]$/;
 | 
			
		||||
    }
 | 
			
		||||
    my $topic = $1; my $type = $2; my $partitions = $3;
 | 
			
		||||
| 
						 | 
				
			
			@ -713,7 +738,7 @@ while(<>) {
 | 
			
		|||
    my $pwrguid = hexify($1); my $rdguid = hexify($2);
 | 
			
		||||
    die unless exists $pwr{$pwrguid} || $pwrguid =~ /[4c][23]$/;
 | 
			
		||||
    die unless exists $rd{$rdguid} || $rdguid =~ /[4c][74]$/;
 | 
			
		||||
    die if defined $pwr{$pwrguid}->{tdel};
 | 
			
		||||
    #die if defined $pwr{$pwrguid}->{tdel}; # the order reversal is possible, however unlikely
 | 
			
		||||
    #next if $pwrguid =~ /[4c]2$/;
 | 
			
		||||
    $pwr{$pwrguid}->{matches}->{$rdguid} = {};
 | 
			
		||||
    $rd{$rdguid}->{matches}->{$pwrguid} = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -722,7 +747,7 @@ while(<>) {
 | 
			
		|||
    my $wrguid = hexify($1); my $prdguid = hexify($2); my $bereader = $3 ne '';
 | 
			
		||||
    die unless exists $wr{$wrguid} || $wrguid =~ /[4c][23]$/;
 | 
			
		||||
    die unless exists $prd{$prdguid} || $prdguid =~ /[4c][74]$/;
 | 
			
		||||
    die if defined $prd{$prdguid}->{tdel};
 | 
			
		||||
    #die if defined $prd{$prdguid}->{tdel}; # the order reversal is possible, however unlikely
 | 
			
		||||
    #next if $wrguid =~ /[4c]2$/;
 | 
			
		||||
    my $wr = $wr{$wrguid};
 | 
			
		||||
    my $prd = $prd{$prdguid};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -583,7 +583,7 @@ int double_to_dds_duration(dds_duration_t *dd, double d) {
 | 
			
		|||
    if (d < 0)
 | 
			
		||||
        return -1;
 | 
			
		||||
    double nanosec = d * 1e9;
 | 
			
		||||
    if(nanosec > INT64_MAX) {
 | 
			
		||||
    if(nanosec > (double)INT64_MAX) {
 | 
			
		||||
        *dd = DDS_INFINITY;
 | 
			
		||||
    } else {
 | 
			
		||||
        *dd = (int64_t) nanosec;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,6 @@ static enum tgprint_mode printmode = TGPM_FIELDS;
 | 
			
		|||
static unsigned print_metadata = PM_STATE;
 | 
			
		||||
static int printtype = 0;
 | 
			
		||||
 | 
			
		||||
#define T_SECOND ((int64_t) 1000000000)
 | 
			
		||||
struct tstamp_t {
 | 
			
		||||
    int isabs;
 | 
			
		||||
    int64_t t;
 | 
			
		||||
| 
						 | 
				
			
			@ -351,7 +350,7 @@ static int read_int_w_tstamp(struct tstamp_t *tstamp, char *buf, int bufsize, in
 | 
			
		|||
            posoff = 1;
 | 
			
		||||
        }
 | 
			
		||||
        if (read_int(buf, bufsize, pos + posoff, 1))
 | 
			
		||||
            tstamp->t = atoi(buf + pos) * T_SECOND;
 | 
			
		||||
            tstamp->t = atoi(buf + pos) * DDS_NSECS_IN_SEC;
 | 
			
		||||
        else
 | 
			
		||||
            return 0;
 | 
			
		||||
        while ((c = getc(stdin)) != EOF && isspace((unsigned char) c))
 | 
			
		||||
| 
						 | 
				
			
			@ -411,7 +410,7 @@ static int read_value(char *command, int *key, struct tstamp_t *tstamp, char **a
 | 
			
		|||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 'p': case 'S': case ':': case 'Q': {
 | 
			
		||||
        case 'p': case 'S': case 'C': case ':': case 'Q': {
 | 
			
		||||
            int i = 0;
 | 
			
		||||
            *command = (char) c;
 | 
			
		||||
            while ((c = getc(stdin)) != EOF && !isspace((unsigned char) c)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1165,6 +1164,53 @@ static void pub_do_auto(const struct writerspec *spec) {
 | 
			
		|||
    dds_free(handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_deafmute(const char *args)
 | 
			
		||||
{
 | 
			
		||||
    const char *a = args;
 | 
			
		||||
    bool deaf = false;
 | 
			
		||||
    bool mute = false;
 | 
			
		||||
    dds_duration_t duration = 0;
 | 
			
		||||
    double durfloat;
 | 
			
		||||
    int pos;
 | 
			
		||||
    if (strncmp(a, "self", 4) == 0) {
 | 
			
		||||
        a += 4;
 | 
			
		||||
    } else {
 | 
			
		||||
        printf ("deafmute: invalid args: %s\n", args);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (*a++ != ';') {
 | 
			
		||||
        printf ("deafmute: invalid args: %s\n", args);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    while (*a && *a != ';') {
 | 
			
		||||
        switch (*a++) {
 | 
			
		||||
            case 'm': mute = true; break;
 | 
			
		||||
            case 'd': deaf = true; break;
 | 
			
		||||
            default: printf ("deafmute: invalid flags: %s\n", args); return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (*a++ != ';') {
 | 
			
		||||
        printf ("deafmute: invalid args: %s\n", args);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (strcmp(a, "inf") == 0) {
 | 
			
		||||
        duration = DDS_INFINITY;
 | 
			
		||||
    } else if (sscanf(a, "%lf%n", &durfloat, &pos) == 1 && a[pos] == 0) {
 | 
			
		||||
        if (durfloat <= 0.0) {
 | 
			
		||||
            printf ("deafmute: invalid duration (<= 0): %s\n", args);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (durfloat > (double) (DDS_INFINITY / DDS_NSECS_IN_SEC))
 | 
			
		||||
            duration = DDS_INFINITY;
 | 
			
		||||
        else
 | 
			
		||||
            duration = (dds_duration_t) (durfloat * 1e9);
 | 
			
		||||
    } else {
 | 
			
		||||
        printf ("deafmute: invalid args: %s\n", args);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    dds_domain_set_deafmute (dp, deaf, mute, duration);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *pub_do_nonarb(const struct writerspec *spec, uint32_t *seq) {
 | 
			
		||||
    struct tstamp_t tstamp_spec = { .isabs = 0, .t = 0 };
 | 
			
		||||
    int result;
 | 
			
		||||
| 
						 | 
				
			
			@ -1210,7 +1256,7 @@ static char *pub_do_nonarb(const struct writerspec *spec, uint32_t *seq) {
 | 
			
		|||
                tstamp = dds_time();
 | 
			
		||||
                tstamp_spec.t += tstamp;
 | 
			
		||||
            }
 | 
			
		||||
            tstamp = (tstamp_spec.t % T_SECOND) + ((int) (tstamp_spec.t / T_SECOND) * DDS_NSECS_IN_SEC);
 | 
			
		||||
            tstamp = (tstamp_spec.t % DDS_NSECS_IN_SEC) + ((int) (tstamp_spec.t / DDS_NSECS_IN_SEC) * DDS_NSECS_IN_SEC);
 | 
			
		||||
            if ((result = fn(spec->wr, &d, tstamp)) != DDS_RETCODE_OK) {
 | 
			
		||||
                printf ("%s %d: error %d (%s)\n", get_write_operstr(command), k, (int) result, dds_err_str(result));
 | 
			
		||||
                if (flushflag) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1279,6 +1325,9 @@ static char *pub_do_nonarb(const struct writerspec *spec, uint32_t *seq) {
 | 
			
		|||
        case 'Y': case 'B': case 'E': case 'W':
 | 
			
		||||
            non_data_operation(command, spec->wr);
 | 
			
		||||
            break;
 | 
			
		||||
        case 'C':
 | 
			
		||||
            do_deafmute(arg);
 | 
			
		||||
            break;
 | 
			
		||||
        case ':':
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
| 
						 | 
				
			
			@ -1311,7 +1360,7 @@ static char *pub_do_nonarb(const struct writerspec *spec, uint32_t *seq) {
 | 
			
		|||
//            command = *line++;
 | 
			
		||||
//            if (*line == '@') {
 | 
			
		||||
//                if (*++line == '=') { ++line; tstamp_spec.isabs = 1; }
 | 
			
		||||
//                tstamp_spec.t = T_SECOND * strtol(line, (char **) &line, 10);
 | 
			
		||||
//                tstamp_spec.t = DDS_NSECS_IN_SEC * strtol(line, (char **) &line, 10);
 | 
			
		||||
//            }
 | 
			
		||||
//        case '{': {
 | 
			
		||||
//            write_oper_t fn = get_write_oper(command);
 | 
			
		||||
| 
						 | 
				
			
			@ -1324,10 +1373,10 @@ static char *pub_do_nonarb(const struct writerspec *spec, uint32_t *seq) {
 | 
			
		|||
//                int diddodup = 0;
 | 
			
		||||
//                if (!tstamp_spec.isabs) {
 | 
			
		||||
//                    DDS_DomainParticipant_get_current_time(dp, &tstamp);
 | 
			
		||||
//                    tstamp_spec.t += tstamp.sec * T_SECOND + tstamp.nanosec;
 | 
			
		||||
//                    tstamp_spec.t += tstamp.sec * DDS_NSECS_IN_SEC + tstamp.nanosec;
 | 
			
		||||
//                }
 | 
			
		||||
//                tstamp.sec = (int) (tstamp_spec.t / T_SECOND);
 | 
			
		||||
//                tstamp.nanosec = (unsigned) (tstamp_spec.t % T_SECOND);
 | 
			
		||||
//                tstamp.sec = (int) (tstamp_spec.t / DDS_NSECS_IN_SEC);
 | 
			
		||||
//                tstamp.nanosec = (unsigned) (tstamp_spec.t % DDS_NSECS_IN_SEC);
 | 
			
		||||
//                line = endp;
 | 
			
		||||
//                result = fn(spec->wr, arb, DDS_HANDLE_NIL, &tstamp);
 | 
			
		||||
//                if (result == DDS_RETCODE_OK && spec->dupwr) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1363,6 +1412,10 @@ static char *pub_do_nonarb(const struct writerspec *spec, uint32_t *seq) {
 | 
			
		|||
//        case 'Y': case 'B': case 'E': case 'W':
 | 
			
		||||
//            non_data_operation(*line, spec->wr);
 | 
			
		||||
//            break;
 | 
			
		||||
//        case 'C':
 | 
			
		||||
//            do_deafmute(arg);
 | 
			
		||||
//            line = NULL;
 | 
			
		||||
//            break;
 | 
			
		||||
//        case 'S':
 | 
			
		||||
//            make_persistent_snapshot(line+1);
 | 
			
		||||
//            line = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -2631,8 +2684,8 @@ int main(int argc, char *argv[]) {
 | 
			
		|||
//            }
 | 
			
		||||
//            tnow = dds_time();
 | 
			
		||||
//            if (m != 0 && tnow < tend) {
 | 
			
		||||
//                uint64_t tdelta = (tend-tnow) < T_SECOND/10 ? tend-tnow : T_SECOND/10;
 | 
			
		||||
//                os_time delay = { (os_timeSec) (tdelta / T_SECOND), (os_int32) (tdelta % T_SECOND)};
 | 
			
		||||
//                uint64_t tdelta = (tend-tnow) < DDS_NSECS_IN_SEC/10 ? tend-tnow : DDS_NSECS_IN_SEC/10;
 | 
			
		||||
//                os_time delay = { (os_timeSec) (tdelta / DDS_NSECS_IN_SEC), (os_int32) (tdelta % DDS_NSECS_IN_SEC)};
 | 
			
		||||
//                os_nanoSleep(delay);
 | 
			
		||||
//                tnow = dds_time();
 | 
			
		||||
//            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue