Static DNS resolver in C++ - c++

I am trying to build a fast DNS resolver in c++ with static libraries (work everywhere). So far so good my version uses gethostbyname and on some servers it doesn't work i get A non-recoverable name server error occurred (NO_RECOVERY). Also when compiling we are getting this warning :
Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
#include <stdio.h>
#include <cstring>
// for dom
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
char* host = "google.com";
int debugLevel = 5;
char* ip_of_domain;
struct hostent *he;
he = gethostbyname(host);
if (he == NULL)
{
switch(h_errno)
{
case HOST_NOT_FOUND:
if(debugLevel >= 3) puts("The host was not found.");
break;
case NO_ADDRESS:
if(debugLevel >= 3) puts("The name is valid but it has no address.");
break;
case NO_RECOVERY:
if(debugLevel >= 3) puts("A non-recoverable name server error occurred.");
break;
case TRY_AGAIN:
if(debugLevel >= 3) puts("The name server is temporarily unavailable.");
break;
}
}
else
{
ip_of_domain = strdup(inet_ntoa(*((struct in_addr *) he->h_addr_list[0])));
}
if(debugLevel >= 4) printf("IP=%s\n",ip_of_domain);
}
The program has to be compatible every where, 32 and 64 bits.
Any solution?
Thanks.

Use c-ares library, here: https://c-ares.haxx.se/. This is a true OS-independent resolver.

Related

Mount a CIFS client/connection with sys/mount

I am trying to make a CIFS connection between my Ubuntu client desktop and my Windows 10 server Desktop, so I can share folders and files though a local network.
My code is the following:
#include <sys/mount.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <string>
using namespace std;
int main()
{
string src = "//xxx.xxx.x.xxx/shared_folder"; //xxx.xxx.x.xxx should be replaced by the server IP. shared_folder is my folder shared on the server side
string dst = "/opt/share";//My shared folder on Linux
string fstype = "cifs";
printf("src: %s\n", src.c_str());
if( -1 == mount(src.c_str(), dst.c_str(), fstype.c_str(), MS_MGC_VAL | MS_SILENT , "username=myemail#hotmail.com,password=mypassword") )
{
printf("mount failed with error: %s\n",strerror(errno));
}
else
printf("mount success!\n");
return 0;
}
But it always returns:
src: //xxx.xxx.x.xxx/shared_folder
mount failed with error: Operation not permitted
[1] + Done "/usr/bin/gdb" --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-fmryivr5.02p" 1>"/tmp/Microsoft-MIEngine-Out-zfdhv3x2.zc5"
Any clue, please?

Windows Sharing file over network NetShareAdd Error 53

I tried to compile this example from microsoft docs for sharing a folder over network however the executable gives an error.
Full Code :
#include "stdafx.h"
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
#include <lm.h>
#pragma comment(lib, "Netapi32.lib")
void wmain(int argc, TCHAR *argv[])
{
NET_API_STATUS res;
SHARE_INFO_2 p;
DWORD parm_err = 0;
if (argc<2)
printf("Usage: NetShareAdd server\n");
else
{
//
// Fill in the SHARE_INFO_2 structure.
//
p.shi2_netname = TEXT("TESTSHARE");
p.shi2_type = STYPE_DISKTREE; // disk drive
p.shi2_remark = TEXT("TESTSHARE to test NetShareAdd");
p.shi2_permissions = 0;
p.shi2_max_uses = 4;
p.shi2_current_uses = 0;
p.shi2_path = TEXT("F:\\abc");
p.shi2_passwd = NULL; // no password
//
// Call the NetShareAdd function,
// specifying level 2.
//
res = NetShareAdd(argv[1], 2, (LPBYTE)&p, &parm_err);
//
// If the call succeeds, inform the user.
//
if (res == 0)
printf("Share created.\n");
// Otherwise, print an error,
// and identify the parameter in error.
//
else
printf("Error: %u\tparmerr=%u\n", res, parm_err);
}
return;
}
Exe command :
ConsoleApplication1.exe myShare
Error Shown :
Error: 53 parmerr=0
However the follwing from cmd works fine :
net share abc=F:\abc
I am unable to figure out what actually the error is and how to resolve that. can anybody help?
I am on windows 11 and code is compiled on VS 2015 Community.
With admin privileges, servername ConsoleApplication1.exe localhost and ConsoleApplication1.exe 127.0.0.1 worked fine.

Reset dlmopen namespace

I have a small program that loads 2 modules (X11, and my own):
#include <fcntl.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
int main(int c, char* argv[])
{
pid_t PID = c > 1 ? atoi(argv[1]) : -1;
if (PID <= 0)
{
fprintf(stderr, "Invalid PID\n");
return -1;
}
const char* path = "/home/brandon/Desktop/mylib.so";
void* x11 = dlmopen(LM_ID_NEWLM, "libX11.so.6", RTLD_NOW);
/*Lmid_t id = 0;
dlinfo(dl, RTLD_DI_LMID, &id);
dl = dlmopen(id, path, RTLD_LAZY);*/
void* dl = dlopen(path, RTLD_LAZY);
if (dl)
{
printf("Loading dll\n");
void (*ptrace_info)(pid_t pid) = (decltype(ptrace_info))dlsym(dl, "ptrace_info");
if (ptrace_info)
{
ptrace_info(PID);
}
dlclose(dl);
printf("Unloaded\n");
}
return 0;
}
If I use dlopen(path, RTLD_*) my module fails to ptrace the specified pid. However, if I uncommented the code above that uses dlmopen everything works fine (even if I create a new namespace, it works)..
If I do not dlmopen(.., X11, ..), it works fine. The only time it does NOT work is if I dlmopen anything and then try to dlopen something else.
Seeing as the only difference is the namespace, is there a way I can use dlopen after using dlmopen?

Error corrupted size vs. prev_size: when trying to open and read a file descriptor in C++

I am having the error: corrupted size vs. prev_size: 0x01fe29e8 on my C++ unit test. I have created a very simple unit test to load a kernel module (I²C) into the OS. First I open a file /root/i2c-tests/i2c-stub.ko without errors. Second I do a fstat also without errors. Third I resize a vector and read the content of a file descriptor. Finally, I use init_module to load the kernel module. The functions have error handling and no error is being caught. Actualy I am loading the kernel module into memory and I can list it using lsmod and I also can write and read from it using i2cset and i2cget. However, I am getting this annoying error: *** Error in ./test/sensorTests': corrupted size vs. prev_size: 0x011cd9e8 ***
Aborted. I guess I have to have a loop to read the file, like is showing here (How to properly error trap read in c to get byte number from a file descriptor) but I do know how to implement this loop and why I should implement it.
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
#define delete_module(name, flags) syscall(__NR_delete_module, name, flags)
class I2CKernelModule : public testing::Test {
public:
I2CKernelModule() {
}
};
TEST_F(I2CKernelModule, TestAddKernelModule) {
char *params;
int fd;
struct stat fileStat;
std::vector<char> fileContent;
params = "chip_addr=0x20";
// command: sudo insmod /root/i2c-tests/i2c-stub.ko chip_addr=0x20
if ((fd = open("/root/i2c-tests/i2c-stub.ko", O_RDONLY)) < 0) {
perror("open");
GTEST_FAIL();
}
if (fstat(fd, &fileStat) < 0) {
perror("fstat");
GTEST_FAIL();
}
fileContent.resize(fileStat.st_size);
if (read(fd, fileContent.data(), fileStat.st_size + 1) == -1) {
perror("read");
GTEST_FAIL();
}
if (close(fd)) {
perror("close");
GTEST_FAIL();
}
if (init_module(fileContent.data(), fileStat.st_size + 1, params) != 0) {
perror("init_module");
GTEST_FAIL();
}
GTEST_SUCCESS_("Kernel module loaded.");
/*
// sudo rmmod i2c_stub
if (delete_module("i2c_stub", O_NONBLOCK) != 0) {
perror("delete_module");
GTEST_FAIL();
}
GTEST_SUCCESS_("Kernel module unloaded.");
*/
}

FastCGI and Apache and C++

I comliled C++ project for FastCGI, copy executable file into www directory, open via browser - and got 500 error (timeout exeption). What do i wrong?
OS Ubuntu 10.05, server: Apache
source C++ code:
#include <fcgi_stdio.h> /* fcgi library; put it first*/
#include <fcgiapp.h>
#include <cstdlib>
#include <iostream>
using namespace std;
int count;
int main(int argc, char** argv) {
/* Response loop. */
while (FCGI_Accept() >= 0) {
cout<<"Content-type: text/html\r\n"
"\r\n"
"<title>FastCGI Hello! (C, fcgi_stdio library)</title>"
"<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>"
"Request number %d running on host <i>%s</i>\n";
}
return 0;
}
When you're in the FCGI_Accept() loop you should be reading data, not writing it.
Check out http://www.fastcgi.com/devkit/doc/fastcgi-prog-guide/apaman.htm