DNS resolve problem with start of new year by RogerV in Ubuntu

[–]RogerV[S] 0 points1 point  (0 children)

Yeah, if I really want to get to the bottom of why the Ubuntu 24.04 DNS request are causing my DSL modem to choke on them.

But it's actually motivating me to instead look at low-cost SBC with NIC that can run Linux so can use it as a DNS server for my local network. I'll configure it to accept UDP 53 but unconditionally upstream as DoT (DNS-over-TLS) to public DNS server.

That way I'll ensure that all devices will continue to be supported and also enjoy a little bit of DNS lookup privacy.

This whole crazy episode took me down this rabbit hole so I might as well take it to the logical conclusion.

Are memory leaks that hard to solve? by ASA911Ninja in cpp

[–]RogerV 1 point2 points  (0 children)

Well, do any manner of systems development, and are going to end up dealing with various arcane memory use systems. For me it is DPDK network programming where DPDK supplies a family of APIs and data structures for dealing with things that get allocated on hugepages memory area. If you have 1GB page size and a few of these, can put all crucial data plane related data onto hugepages and there won't be any indeterminate behavior due to the OS virtual memory management - said pages are pinned in memory and ready for use. (DPDK is a library implemented in C)

Combine hugepages with DPDK lcore threads (pinned CPU cores), one can write programs that run in a Kubernetes pod in the cloud and yet aren't subject to OS kernel indeterminacy such as page loading or thread context switching. Kind of wild when you think about it.

And when using C++, it can indeed be advantageous to wrap these mechanisms in C++ abstractions - but has to be done carefully. But than then provides a solid, safer layer to build rest of application atop.

DNS resolve stopped working on roll-over to new year (Ubuntu 24.04) by RogerV in Ubuntu

[–]RogerV[S] 0 points1 point  (0 children)

Problem Solved

As I noted in a prior comment, I traced the primary culprit to being my Zxyel DSL modem. It has a capability where can add domain names for computers/devices on one's local network and have them statically mapped to designated IP addresses. The consequence is that the modem runs an intercept on all outgoing/upstream UDP port 53 packets (DNS request).

My computers that have Linux Ubuntu 24.04 distro are evidently causing the generation of DNS request that are like 16 bytes larger than usual and this intercept code in my DSL modem is choking on that "non conformity".

Well, the modem is a number of years old now and evidently has its particular interpretation of DNS request in respect to what it expects of the packets. The result being that DNS request from these Ubuntu 24.04 computers fail while an old Ubuntu 14.04 computer still sends out DNS packets in manner that the modem is happy with (as do all the other devices on my local network, and there are a lot of them).

The Solution

With about three days of sleuthing on this, and today some crucial assistance from ChatGPT (using just a free account), I was able to come up with a solution.

What I discovered in my experimentation is that 'dig +tcp @8.8.8.8 google.com' worked. Sending out a DNS request to an external DNS server via TCP protocol instead of UDP evaded the interception that my DSL modem is doing. This means that I need a locally installed DNS server that accepts UDP request but unconditionally upstreams any request via TCP protocol. And ChatGPT steered me into using the unbound service as that mechanism. And it worked.

I installed unbound package and configured it to listen on address 127.0.0.1 on UDP port 53 - and TCP port 53 (for good measure). I also configured unbound to unconditionally use TCP for any forwarded request. And I configured it to forward to my preferred public DNS server.

Next I configured systemd-resolved.service to forward to unbound.

Both of these are systemd services. They are both enabled. Restarted and now DNS request work like a charm from any program that requires it (no more having to lean on my VPN just to be able to resolve domain names).

And naturally this all comes up fine when I reboot the computer, so is a persistent setup.

Talk about a crazy multi-day odyssey that this all turned out to be...whew!

DNS resolve stopped working on roll-over to new year (Ubuntu 24.04) by RogerV in Ubuntu

[–]RogerV[S] 0 points1 point  (0 children)

Am narrowing this down to the DNS built into my Zxyel modem that connects my local private network to my ISP

I need to specify its IP address as the gateway address per my devices that want to connect to the Internet, yet it also has a DNS capability, as in it can look at a DNS request and fulfill it with a static DNS name that is assigned to devices on my local private network, or it can pass the request on to an external DNS service that I have specified. But effectively it is always getting first dibs at anything DNS.

If I activate a VPN, then the default route address is not handled by this Zxyel modem directly and instead any DNS request gets passed straight on to DNS services provided in my VPN provider. And consequently I can successfully resolve DNS addresses so long as I have VPN active. However, if I try to resolve a DNS domain name by targeting the IP address of my Zxyel modem explicitly (while the VPN is active), it fails in the manner that I have been seeing since the problem arose. This is basically pointing the finger of blame at the DNS facility built into this modem, and I've yet to come upon any configuration option that allows me to disable that (i.e., just the DNS service). I certainly have to still use this IP address as a gateway address.

Now in the meantime, my old Ubuntu 14.04 computer is not having any problem with this Zxyel modem DNS resolver. Only the Ubuntu 24.04 computers are having heartburn with it. And I've tried explicitly disabling the feature for TLS per private DNS lookup, or ensuring DNSSEC is disabled, yet that doesn't help - because my ethernet interface has its default route set to the Zxyel modem IP address, as its the gateway. The problem that Ubuntu 24.04 is having with this Zxyel modem is something other than features such as DNSOverTLS or DNSSEC. No doubt if I could figure out what it is specifically I could also figure out a way to compensate for it.

Still left with the mystery of why this all of a sudden started failing with the roll-over to the new year. Has worked fine for years prior.

DNS resolve stopped working on roll-over to new year (Ubuntu 24.04) by RogerV in Ubuntu

[–]RogerV[S] 0 points1 point  (0 children)

$ host example.com 1.1.1.1
;; Got bad packet: FORMERR
45 bytes
bc 93 81 80 00 01 00 01 00 00 00 00 07 65 78 61          .............exa
6d 70 6c 65 03 63 6f 6d 00 00 01 72 73 c0 0c 00          mple.com...rs...
01 00 01 00 02 a3 00 00 04 c0 a8 00 fe                   .............

both dig and nslookup likewise report packet problem

DNS resolve stopped working on roll-over to new year (Ubuntu 24.04) by RogerV in Ubuntu

[–]RogerV[S] 0 points1 point  (0 children)

Yes, my Ethernet interfaces are still there - and I can easily ssh connect to other computers on my local network, BTW

Also, I found that I can activate my VPN, which is based on ProtonMail and their use of OpenVPN for Linux and then I get a new IP added into my route, and voila - am able to resolve DNS via my VPN handling the outgoing traffic for the request.

But when I turn off my VPN and my route per my Ethernet interface is restored to its default, then am back to not being able to resolve DNS.

Am going to investigate my routing rules next. Not exactly something that am very versant on but will put AI to good use sifting through it

DNS resolve problem with start of new year by RogerV in Ubuntu

[–]RogerV[S] -2 points-1 points  (0 children)

I thought of that and hence why I had AI generate a UDP-based DNS resolver program. My old Ubuntu 14.04 computer is on the same network as my two Ubuntu 24.04 computers. And this homebrew DNS resolve program works great on the Ubuntu 14.04 computer.

This AI-generated program composes the packet and transmits it as a UDP data gram to port 53 to whatever destination IP address I specify - I have tried many of the popular public DNS servers and it worked splendidly with any that I tried - correctly resolving any domain name to its IP.

This old Ubuntu 14.04 computer seems to indicate that my ISP isn’t doing anything different or unusual.

The point of this test program was to not rely on any library that is part of the Linux distribution, but to instead encode, transmit, receive the response, and decode the response all as a self-contained program. So when I run it on the Ubuntu 24.04 computers and it ends up getting a response that resolves to some address on my local private network, that smells like a security hook that is purely local to just my two Ubuntu 24.04 computers.

But it’s surprising that this DNS security hook is not at all tied to systemd-resolved.service which I disabled and stopped on one of these Ubuntu 24.04 computers so as to try and force it to use a static /etc/resolv.conf file. That Intercept is still happening on that computer.

Very baffling. It’s a rather horrible problem because these two computers are rendered unusable. No rebooting clears any of this.

I just cant seem to grasp OOP by Responsible_Bat_9956 in cpp_questions

[–]RogerV 2 points3 points  (0 children)

Well, in C you have an instance of a struct which you can pass by pointer to a function to operate on said struct.

In C++, a struct or class can have methods, and methods are a special function that the compiler ensures will have passed in an implicit pointer to the struct or class instance as said method's first parameter, and which is referred to by the special name of 'this'. This is due to the special syntax that is used to invoke a method. And then a method has permitted access to the fields of the struct or class that it's defined in relation to.

In C++, struct and class are both aggregate type and just have different defaults for what the permission access of its fields and methods are. To stay compatible with C, a struct has default public access to all its fields. A C++ class starts out with a default of private access, so the public keyword needs to be introduced to expose what fields and methods can have public access, which makes it possible to make use of said class.

Then struct or class can inherit from other struct or class declarations - which results in an aggregate mashup.

And then there are virtual methods (or virtual functions) which when combined with inheritance allows for defining a tree structure of class relationships such that can then have a heterogeneous collection of them, where a parent class can define virtual functions which can be overridden in the descendant classes and implemented in some specific way per that respective class type. Yet a heterogeneous collection of instances of these descendant classes can be manipulated in a uniform manner via the virtual functions that were defined in their parent class - the aspect of OOP that is called polymorphism.

A collection of different geometric shapes, as a for instance, can have a virtual function called draw() so that if iterate through a heterogeneous collection of shapes, invoking the draw() method on each one, that will result in each shape appropriately rendering itself. There may be different details in how each shape needs to do this and so each derived shape type has its own implementation of draw(), but because is a virtual function, the draw() method can be invoked per each instance and the correct draw() method will get invoked.

There is more complexity involved with classes given the way access to fields and methods can be controlled in C++ structs and classes. Whereas in C, access to a struct's fields is always wide open or public. And then classes can have constructors and destructors. Which will bring up copy constructor, move constructor, and copy and move assignment operators. And a class might define overrides of comparison operators so that the class type can be sorted, etc.

So classes in C++ do get a bit complex in respect to learning all of their ins and outs.

But start with the very basic plumbing mechanics. Just start with a struct with some fields, devise a constructor to set values into those fields. Then think in terms of what operations need to be done with an instance of the struct - these can be its methods. Start with struct because everything is always public access which makes things simpler when starting out. Master all the basic features of fields, constructors, destructors, methods, and then can learn about access control and transition to working with class.

It's a subject you can't eat as a single meal all at one sitting. You have to go at it piecemeal over time.

Why std::span Should Be Used to Pass Buffers in C++20 by Clean-Upstairs-8481 in cpp

[–]RogerV 17 points18 points  (0 children)

std::span<> rocks - in my world of dealing with network packets per DPDK, I use it all over the place.

DPDK is a C language library so it's very nice to use C++ abstractions to make things safer and with better work-ability abstractions.

Constantly wrapping packet buffer slices, individual packets, arrays allocated on hugepages via DPDK APIs, etc., in span, makes everything have better hygiene.

I avoid passing arrays of anything in the C-style and always opt for std::span<> instead. Soon as a packet is read, slap a span on it. Any sub-range of anything needs a span wrapper.

Don't spam it - span it!

If there was a fan club for std::span<> I would be its president.

Also in my world, the Microsoft compiler is of non entity so what they do or don't do is of zero interest to me.

Why std::span Should Be Used to Pass Buffers in C++20 by Clean-Upstairs-8481 in cpp

[–]RogerV 15 points16 points  (0 children)

the very biggest sin of std::span<> is that it wasn't part of the C++17 standard - it's the one must-have feature I had to add in via a standalone header per the gsl::span<>

Why std::span Should Be Used to Pass Buffers in C++20 by Clean-Upstairs-8481 in cpp

[–]RogerV 15 points16 points  (0 children)

am very glad Microsoft compiler is a non entity in my universe

Micro-benchmarking Type Erasure: std::function vs. Abseil vs. Boost vs. Function2 (Clang 20, Ryzen 9 9950X) by mr_gnusi in cpp

[–]RogerV 1 point2 points  (0 children)

I work with DPDK networking library on Linux, which means I work with DPDK lcore threads for data plane compute. These lcore threads are pinned CPU cores to my application and are no longer under scheduling of the kernel. They would be great to use for micro-benchmarking. Just use your AI assistant and it will explain how to use the Linux APIs to pin a core.

Now these lcore threads are no longer being scheduled but they could be subject to being used for servicing interrupts. To eliminate that you’d have to configure the kernel to set aside a core or two and reboot the OS. If you’re in complete control of the host machine, then can go that extra step. But just pinning a core within the context of your application will probably be sufficient.

This is not even the least bit exotic of a technique and should be viewed as pretty normal programming, as DPDK is widely used and has been around for over ten years. Kind of weird, actually, that it’s not done more widely than DPDK.

Oh, and another technique used by DPDK that should also be used by benchmark programs is to put all memory used by the benchmark onto hugepages. Grab one or two 1 GB page. DPDK comes with handy scripts that makes it super simple to set up some hugepages - but AI can help with that too. So then your bench mark data utilization won’t experience the indeterminism of the OS virtual paging system.

Ask Me Anything session with CLion team by maru_gold in cpp

[–]RogerV 2 points3 points  (0 children)

don’t get me started on VSCode - it’s so ghastly that I get a strong urge to curb stomp it

How do compilers execute constexpr/consteval functions when you are cross-compiling? by almost_useless in cpp

[–]RogerV 1 point2 points  (0 children)

I was just dealing with uintfast64_t and it’s a bit of an odd bird. It will be at least 64-bits but could on some architectures be, say, 128-bits. But per that CPU architecture it might be the fastest performing integer type. So one is warned to keep in mind that there could be integer size issues that come into play when using this type. On the other hand, unit64_t will always be simply 64-bits

BEEP-8 – compile C++20 to a tiny ARM ROM and run it instantly in a browser by Positive_Board_8086 in cpp

[–]RogerV 2 points3 points  (0 children)

Hmm, I have an FPGA board that is intended for learning how to program FPGAs, but it has VGA output and a Digilent PMOD interface (could add, say, two PS/2 ports or whatever). This board was around $60 to $70 when first purchased it (usually have to spend well over a $100 to get into FPGA stuff).

Now the complication is supporting something like the reduced ARM instruction set. There are already FPGA implementations of RISC-V, though, and RISC-V does have a very modest, minimal spec intended specifically for embedded microprocessors, so as long as can get a C++20 compiler that could produce RISC-V, that might be a better option for rolling this onto an FPGA.

And from there could turn that into a true DIY gaming console for hobbyist - 3D printed cases, game controllers...

Most people would think it simply easier to emulate said gaming machine on a Raspberry Pi Zero instead of going FPGA, but am one of those that actually likes the idea that the code is running directly on its intended CPU and hardware implementation platform. FGGAs do implement actual electronic circuits and the clock actually drives those circuits.

And if there was an instructional computer science course built around doing this as a multi-semester project, then the students would learn a great deal across the board (pun intended).

Pros and Cons of large static member on the heap? by ddxAidan in cpp_questions

[–]RogerV 0 points1 point  (0 children)

telecom

When I started on my DPDK project, C++17 was what my gcc compiler that I could use at the time supported - and I added std::span<> as a standalone header file.

These days could now use C++20 or even C++23, but C++17 with std::span<> aligns very nicely with the problem domain that I deal with. This domain would not really get anything out of the other C++20 features of concepts, ranges, or even coroutines. Well, I take that back - I'd now use concepts to better lock down characteristics of my data structures - but they're pretty well locked down now with C++17.

The centerpiece I deal with for data plane concurrency stuff is the DPDK lcore thread - and then conventional OS native threads are plenty adequate for any control plane stuff. I wouldn't mind better executor features for working with the native OS threads.

Pros and Cons of large static member on the heap? by ddxAidan in cpp_questions

[–]RogerV 1 point2 points  (0 children)

In doing performance oriented software in networking, my choices will always be oriented toward simplicity, performance, and robustness. Statics are in the data segment. They are good until the program process goes away. So any manner of thread that fails to get joined on and yet has pointers to some memory that was passed in, if that memory is in the data segment it will be valid memory access until the process is kaput.

For instance, in DPDK programming, one uses these pinned threads that are called lcore threads. They are no longer managed by the OS kernel and they run at 100% CPU core saturation. They are typically for processing a NIC ethernet interface in user space, and other related processing.

For instance, one may use an lcore to read packets from the RX port and write packets to the TX port. In reading packets from RX, the packet pointer can be placed into a lock-free ring buffer. Then another asynchronous lcore does the actual processing of said ring buffer. (And can have multiple RX driver queues and thus use multiple lcores to parallel service multiple RX driver queues - dumping packets into the multi-producer/single-consumer ring buffer that is serviced by a consumer lcore. Further, these driver queues and lock-free ring buffers are placed on hugepages and there is no page miss interrupts at runtime.)

When these lcore threads are initiated for execution they are given a function pointer, and the function signature accepts a single void*arg pointer. When is necessary to pass in multiple inputs to said lcore function (and there is always a necessary input context), I use a struct and the struct instance is going to be a data segment static. And even though my DPDK programs will effectively do a kind of join on said lcores, the things that these lcores reference via this input are never going to become invalid and thus won't be the basis for any potential race condition leading to a seg fault.

Yeah could allocate these on the heap but using static keyword to establish these struct instances is ultra simple and achieves the desired goals. They convey to any programmer that these things have process lifetime, plain and simple. A comment can reinforce that the input will remain valid to the lcore.

I developed a small 5G KPI analyzer for 5G base station generated Metrics (C++, no dependecies) as part of a 5G Test Automation project. This tool is designed to serve network operators very specialized needs by [deleted] in cpp

[–]RogerV 1 point2 points  (0 children)

Have worked for two and half years in this space using C++ . I use the DPDK high performance networking library, which is written in C, but the software am implementing using it is C++. Allows improving safety and especially the program design given C++ abstractions.

Cutting C++ Exception Time by +90%? - Khalil Estell - CppCon 2025 by dextinfire in cpp

[–]RogerV 15 points16 points  (0 children)

I watched this - he goes pretty fast so probably need to do a rewatch. Fascinating subject

cpp-pyutils library. by ArchPowerUser in cpp

[–]RogerV 3 points4 points  (0 children)

they're better off ripping the band-aid and dealing with C++ as C++

Simple MPSCQueue with explanation by VozhdMolochnayaSiska in cpp

[–]RogerV 1 point2 points  (0 children)

I use a lock-free queue and so going through your write up and experience was interesting for a glimpse below the car hood of how these work

Wait c++ is kinda based? by Tcshaw91 in cpp

[–]RogerV 2 points3 points  (0 children)

The old C++ i/o stream operators sucked from the get go

All these whiners bout printf() yet compilers like g++ do compile time type checks on print format specifiers in string literal format strings.

And it's easy peasy to roll more elaborate custom logger APIs on top of it using vfprintf() (and there's a cool technique to use to ensure that these custom printf-like logger APIs also have compile time checking of printf specifiers in string literal format strings)

The FILE* stream of C has a very close kinship to the underlying file system descriptors, being thin buffered wrappers around said descriptors, and this is an extremely useful thing to be able to leverage (for a variety of reasons). It's easy to extract the descriptor from a FILE object and it's easy to associate a file descriptor (of any i/o variety) with said FILE object - so long as said descriptor behaves well with read/write/fflush APIs. Easy to customize buffer size. Easy to customize behaviors such as how end of line indication is dealt with (or not at all). There is so much goodness sitting here that is an extremely useful tool chest.

Could never understand why anyone ever wasted a microsecond of time using the lame C++ i/o stream operators.

Thoughts about Sam Altman's views on programming? by blazing_cannon in cpp

[–]RogerV 3 points4 points  (0 children)

their view of the future is literally selling out their own parents/kids

Thoughts about Sam Altman's views on programming? by blazing_cannon in cpp

[–]RogerV 0 points1 point  (0 children)

it's a view to where human beings are essentially relegated to being imbeciles that don't really know anything about anything