UDP winsock chat program receives -1 from recvfrom() and sendto() - c

Currently, we are producing UDP chat programs using MFC and C.
I'm working on both bind because I have to send incoming messages from the server and client.
An error occurs when recvfrom() and sendto(), they return -1.
I don't know what the problem is. I searched it and did what I did, but it's not working.
Why does sendto() and recvfrom() return -1?
I don't know what the problem is.
server Code
static UINT UdpServerFunc(LPVOID pVoid)
{
CServerDlg *dlg = (CServerDlg *)AfxGetApp()->m_pMainWnd;
//------------------------------------------------------
CString slniPath;
slniPath.Format(_T("./NetworkPath.ini"));
TCHAR ServerPort[MAX_PATH];
int ServerPort_Num;
GetPrivateProfileString(_T("ServerInfo"), _T("Port"), _T(""), ServerPort, MAX_PATH, slniPath);
ServerPort_Num = _ttoi(ServerPort);
//------------------------------------------------------
//Startup Winsock
WSADATA wsaData;
int retval = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (retval != 0)
{
AfxMessageBox("WSAStartup() Error\n");
return 0;
}
//SOCKET
dlg->server_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//IPPROTO_UDP or PPROTO_HOPOPTS
if (dlg->server_sock == SOCKET_ERROR)
{
AfxMessageBox("Socket() Error\n");
return 0;
}
ZeroMemory(&dlg->server_addr, sizeof(dlg-> server_addr));
dlg->server_addr.sin_family = AF_INET;
dlg->server_addr.sin_port = htons(ServerPort_Num); //30112
dlg->server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
dlg->client_addr.sin_family = AF_INET;
dlg->client_addr.sin_port = htons(ServerPort_Num);
dlg->client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
retval = bind(dlg->server_sock, (SOCKADDR*)&dlg->server_addr, sizeof(dlg->server_addr));
AfxMessageBox("server start");
if (retval == SOCKET_ERROR) {
AfxMessageBox("bind() ERROR\n");
return -1;
}
//Data Communication
int addrlength;
char buf[BUFFER_SIZE];
int recv_size;
while (1)
{
//recvfrom()
addrlength = sizeof(dlg->client_addr);
recv_size = recvfrom(dlg->server_sock, reinterpret_cast<char*>(buf), BUFFER_SIZE, 0, (SOCKADDR*)&dlg->client_addr, &addrlength);
if (recv_size == SOCKET_ERROR)
{
AfxMessageBox("recvfrom() Error");
break;
}
//Data print
buf[recv_size] = '\0';
CString strMsg;
strMsg = CString(buf, recv_size);
dlg->m_ListChat.AddString(strMsg);
strMsg = "";
}
closesocket(dlg->server_sock);
WSACleanup;
}
Server Sendto Code
void CServerDlg::OnBnClickedButton2()
{
CServerDlg *dlg = (CServerDlg *)AfxGetApp()->m_pMainWnd;
CString strText = _T("");
char Text[BUFFER_SIZE];
dlg->m_edit_chat.GetWindowText(strText);
strcpy(Text, strText);
int send_size = sendto(dlg->server_sock, Text, strlen(Text), 0, (sockaddr*)&dlg->client_addr, sizeof(dlg->client_addr));
if (send_size == SOCKET_ERROR)
{
AfxMessageBox("sendto() Error");
}
else
{
dlg->m_ListChat.AddString(strText);
}
}
Client Code
static UINT ClientUdpThreadFunc(LPVOID pVOID) {
CClientTestDlg *dlg = (CClientTestDlg *)AfxGetApp()->m_pMainWnd;
CString slniPath;
slniPath.Format(_T("./NetworkPath.ini"));
TCHAR ServerPort[MAX_PATH];
int ServerPort_Num;
GetPrivateProfileString(_T("ServerInfo"), _T("Port"), _T(""), ServerPort, MAX_PATH, slniPath);
ServerPort_Num = _ttoi(ServerPort); //30112
TCHAR ServerIp[MAX_PATH];
int ServerIp_Num;
GetPrivateProfileString(_T("ServerInfo"), _T("IP"), _T(""), ServerIp, MAX_PATH, slniPath);
ServerIp_Num = _ttoi(ServerIp); //127.0.0.1
//--------------------------------------------------
//StartUp Winsock
WSADATA wsaData;
int retval = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (retval != 0)
{
AfxMessageBox("WSAStartup() Error\n");
return 0;
}
//socket
dlg->clnt_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (dlg->clnt_sock == SOCKET_ERROR) {
AfxMessageBox(_T("socket() Error"));
return 0;
}
ZeroMemory(&dlg->ServerAddr, sizeof(dlg->ServerAddr));
dlg->ServerAddr.sin_family = AF_INET;
dlg->ServerAddr.sin_port = htons(ServerPort_Num);
dlg->ServerAddr.sin_addr.s_addr = inet_addr(SERVERIP);
/*
dlg->FromServer.sin_family = AF_INET;
dlg->FromServer.sin_port = htons(ServerPort_Num);
dlg->FromServer.sin_addr.s_addr = inet_addr(SERVERIP);
*/
retval = bind(dlg->clnt_sock, (SOCKADDR*)&dlg->ServerAddr, sizeof(dlg->ServerAddr));
if (retval == SOCKET_ERROR) {
AfxMessageBox("bind() ERROR\n");
return -1;
}
//Data Communication
CString strMsg;
int addrlength;
char buf[BUF_SIZE];
int recv_size;
while (1) {
addrlength = sizeof(dlg->FromServer);
recv_size = recvfrom(dlg->clnt_sock, reinterpret_cast<char*>(buf), BUF_SIZE, 0, (sockaddr*)&dlg->FromServer, &addrlength);
if (recv_size == SOCKET_ERROR)
{
AfxMessageBox("recvfrom() ERROR");
break;
}
else
{
//Data print
buf[recv_size] = '\0';
strMsg = CString(buf, recv_size);
dlg->m_listChat.AddString(strMsg);
strMsg = "";
}
}
closesocket(dlg->clnt_sock);
WSACleanup;
}
Client Sendto Code
void CClientTestDlg::OnBnClickedButtonSend()
{
CClientTestDlg *dlg = (CClientTestDlg *)AfxGetApp()->m_pMainWnd;
CString UdpStrText = _T("");
char Text[BUF_SIZE];
m_editChat.GetWindowText(UdpStrText);
strcpy(Text, UdpStrText);
int UdpRtn;
UdpRtn = sendto(dlg->clnt_sock, Text, strlen(Text), 0, (SOCKADDR*)&dlg->ServerAddr, sizeof(dlg->ServerAddr));
if (UdpRtn == SOCKET_ERROR)
{
AfxMessageBox("sendto() ERROR\n %s");
}
closesocket(dlg->clnt_sock);
}

Related

Executing two commands with libssh2

I wrote this C code that uses the libssh2 library to connect to a ssh server and get the output of a command executed on the server.
Currently the code works fine, it's connecting to the ssh server and obtains the output of executed command from custom_command variable.
The problem is that I want to make it obtain the output of two commands, for example to obtain the output of custom_command and custom_command2 variables in the same libssh2 channel.
I tried with this but it doesen't work
while((rc = libssh2_channel_exec(channel, custom_command)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
while((rc = libssh2_channel_exec(channel, custom_command2)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
Does anyone know how I can modify this code to work as I said above?
//COMPILE COMMAND: gcc program.c -o program -lssh2
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include "libssh2_config.h"
#include <libssh2.h>
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
{
struct timeval timeout;
int rc, dir;
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(socket_fd, &fd);
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
{
readfd = &fd;
}
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
{
writefd = &fd;
}
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
return rc;
}
int main()
{
//LOGIN CREDENTIALS
char *hostname = "127.0.0.1";
char *username = "vboxuser";
char *password = "changeme";
char *custom_command = "uptime";
char *custom_command2 = "hostname"
int port = 22;
int s_sock;
struct sockaddr_in addr;
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
int rc, exitcode;
rc = libssh2_init(0);
if(rc != 0)
{
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
return 1;
}
s_sock = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr = inet_addr(hostname);
if(setsockopt(s_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
{
perror("setsockopt failed\n");
}
if(setsockopt(s_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
{
perror("setsockopt failed\n");
}
if(connect(s_sock, (struct sockaddr *)(&addr), sizeof(struct sockaddr_in)) != 0)
{
return -1;
}
session = libssh2_session_init();
if(!session)
{
return -1;
}
while((rc = libssh2_session_handshake(session, s_sock)) == LIBSSH2_ERROR_EAGAIN);
if(rc)
{
return -1;
}
while((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
if(rc)
{
goto shutdown;
}
while((channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN )
{
waitsocket(s_sock, session);
}
if(channel == NULL)
{
goto shutdown;
}
while((rc = libssh2_channel_exec(channel, custom_command)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
if(rc != 0)
{
goto shutdown;
}
for(;;)
{
int rc;
do
{
char command_output[65500];
rc = libssh2_channel_read(channel, command_output, sizeof(command_output));
if(rc > 0)
{
fprintf(stderr, "\nSuccessfully Login!\n \nuser:%s \npassword:%s \nhost:%s \nport:%d\n", username, password, hostname, port);
fprintf(stderr, "\nCommand output: %s\n", command_output);
goto shutdown;
}
else
{
if(rc != LIBSSH2_ERROR_EAGAIN)
{
goto shutdown;
}
}
}
while(rc > 0);
if(rc == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
else
{
break;
}
}
while((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
exitcode = 127;
if(rc == 0)
{
exitcode = libssh2_channel_get_exit_status(channel);
}
libssh2_channel_free(channel);
close(s_sock);
channel = NULL;
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
libssh2_exit();
exit(0);
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
close(s_sock);
libssh2_exit();
return 0;
}

Nothing read after SSL_handshake

I try to make a SSL connection, until the SSL_handshake. After the handshake, there is nothing to read from the socket. There is something written to the socket from the client so I expect a response of the server. The socket is connected the whole process, so I don't know what's wrong. The code is displayed under and I have placed comments where the process fails.
struct ssl_information {
int connected;
int sock;
BIO *bio_read;
BIO *bio_write;
SSL *ssl;
SSL_CTX *ctx;
};
void ssl_connection_init()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
void ssl_disconnect(struct ssl_information *ssl)
{
if(!ssl->connected) return;
if(ssl->ctx) SSL_CTX_free(ssl->ctx);
if(ssl->ssl) {
SSL_shutdown(ssl->ssl);
SSL_free(ssl->ssl);
}
close(ssl->sock);
ssl->connected = 0;
}
int ssl_read_socket(struct ssl_information *ssl)
{
int rc;
unsigned char buffer[4096];
rc = read(ssl->sock, buffer, sizeof(buffer)); \\reads nothing on the last call
if(rc == 0 || rc == -1) return 0;
BIO_write(ssl->bio_read, buffer, rc);
return 1;
}
int ssl_write_socket(struct ssl_information *ssl)
{
int rc;
unsigned char buffer[4096];
rc = BIO_read(ssl->bio_write, buffer, sizeof(buffer));
if(write(ssl->sock, buffer, rc) != rc) return 0;
return 1;
}
int tcp_connection(char *ip, int port)
{
int flags, rc, sock;
struct sockaddr_in address;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1) return -1;
flags = fcntl(sock, F_GETFL);
rc = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip);
address.sin_port = htons(port);
connect(sock, (struct sockaddr *)&address, sizeof(address));
return sock;
}
struct ssl_information ssl_connection(char *ip, int port)
{
fd_set read_file_descriptor, write_file_descriptor;
static struct ssl_information ssl;
ssl.sock = tcp_connection(ip, port);
if(ssl.sock == -1) {
ssl.connected = 0;
return ssl;
}
ssl.bio_read = BIO_new(BIO_s_mem());
ssl.bio_write = BIO_new(BIO_s_mem());
ssl.ctx = SSL_CTX_new(TLS_method());
ssl.ssl = SSL_new(ssl.ctx);
SSL_set_connect_state(ssl.ssl);
SSL_set_bio(ssl.ssl, ssl.bio_read, ssl.bio_write);
while(1) {
FD_ZERO(&read_file_descriptor);
FD_ZERO(&write_file_descriptor);
if(SSL_in_init(ssl.ssl)) SSL_do_handshake(ssl.ssl);
if(SSL_is_init_finished(ssl.ssl)) break;
FD_SET(ssl.sock, &read_file_descriptor);
if(BIO_pending(ssl.bio_write)) FD_SET(ssl.sock, &write_file_descriptor);
switch(select(FD_SETSIZE, &read_file_descriptor, &write_file_descriptor, 0, 0)) {
case -1:
case 0:
printf("Failed to monitor socket!\n");
ssl_disconnect(&ssl);
return ssl;
default:
if(FD_ISSET(ssl.sock, &read_file_descriptor)) {
if(!ssl_read_socket(&ssl)) {
printf("Failed to read from socket!\n");
ssl_disconnect(&ssl);
return ssl;
}
}
if(FD_ISSET(ssl.sock, &write_file_descriptor)) {
if(!ssl_write_socket(&ssl)) {
printf("Failed to write to socket!\n");
ssl_disconnect(&ssl);
return ssl;
}
}
}
}
ssl.connected = 1;
return ssl;
}
int main()
{
struct ssl_information ssl;
char response[4096];
ssl = ssl_connection(ip, port);
if(!ssl.connected) {
ssl_disconnect(&ssl);
return 0;
}
BIO_write(ssl.bio_write, message, sizeof(message)); //message is of course set to something
ssl_write_socket(&ssl);
ssl_read_socket(&ssl); \\returns 0
BIO_read(ssl.bio_read, response, sizeof(response)); \\ reads nothing
printf("response: %s\n", response);
return 1;
}

make a https get request in linux based on openssl

guys.
I want to create a https get request on linux with openssl. I made the code from google and my mind. after i run the code,there is something happened, i think the RecvPacket() function has problem,but i do not know how to fix, please tell me how to fix it.
the website where i want to get is https://git.20202060.xyz.it just has a jpg file,what i want to do is download the picture to local file,but now i even can not get the https response,the i could not cut the picture out.
here is code.
SSL *ssl;
int sock;
int RecvPacket()
{
int len = 1024;
char buf[100000] = {'\0'};
if (SSL_read(ssl, buf, 1024) > 0)
{
printf("Receiving . . . .\n");
while (len = 1024)
{
// len = SSL_read(ssl, buf, 1024);
len = SSL_read(ssl, buf, 1024);
buf[len] = '\0';
printf("%s", buf);
if (len < 0)
{
break;
}
}
}
if (len < 0)
{
int err = SSL_get_error(ssl, len);
if (err == SSL_ERROR_WANT_READ)
return 0;
if (err == SSL_ERROR_WANT_WRITE)
return 0;
if (err == SSL_ERROR_ZERO_RETURN || err == SSL_ERROR_SYSCALL || err == SSL_ERROR_SSL)
return -1;
}
}
int SendPacket(const char *buf)
{
int len = SSL_write(ssl, buf, sizeof(buf));
if (len > 0)
{
fprintf(stderr, "Writing . . . . \n");
}
if (len < 0)
{
int err = SSL_get_error(ssl, len);
switch (err)
{
case SSL_ERROR_WANT_WRITE:
printf("SSL_ERROR_WANT_WRITE\n");
return 0;
case SSL_ERROR_WANT_READ:
printf("SSL_ERROR_WANT_READ\n");
return 0;
case SSL_ERROR_ZERO_RETURN:
printf("SSL_ERROR_ZERO_RETURN\n");
case SSL_ERROR_SYSCALL:
printf("SSL_ERROR_SYSCALL\n");
case SSL_ERROR_SSL:
printf("SSL_ERROR_SSL\n");
default:
return -1;
}
}
}
int main(int argc, char *argv[])
{
int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
printf("Error creating socket.\n");
return -1;
}
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("119.28.113.108"); // address of 20202060.xyz
sa.sin_port = htons(443);
socklen_t socklen = sizeof(sa);
if (connect(sockfd, (struct sockaddr *)&sa, socklen))
{
printf("Error connecting to server.\n");
return -1;
}
//openssl initialize
SSL_library_init();
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();
SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
ssl = SSL_new(ctx);
if (!ssl)
{
printf("Error creating SSL.\n");
log_ssl();
return -1;
}
//creat an ssl connection and attach it to the socket
sock = SSL_get_fd(ssl);
SSL_set_fd(ssl, sockfd);
SSL_set_connect_state(ssl);
int err = SSL_connect(ssl);
if (err != 1)
{
printf("Error creating SSL connection. err=%x\n", err);
log_ssl();
fflush(stdout);
return -1;
}
printf("SSL connection using %s\n", SSL_get_cipher(ssl));
char request[1024] = {'\0'};
// char *request_test = "Get /dog.jpg HTTP/1.1\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)\r\nHost:https://20202060.xyz\r\nConnection: Close\r\n";
char host[100] = "https://git.20202060.xyz";
// char ip[30] = "119.28.113.108";
sprintf(request,
"GET /dog.jpg HTTP/1.1\r\n"
"Host: %s\r\n"
"Accept: */*\r\n"
"User-Agent:Mozilla/5.0\r\n"
"Connection: Close\r\n",
host);
SendPacket(request);
RecvPacket();
SSL_shutdown(ssl);
SSL_free(ssl);
close(sockfd);
return 0;
}

Unexpected End-of-file Error, Looked for common causes and can't find any

I'm trying to edit a branch of an open-source project, but one of the files fails to compile with a "C1004: Unexpected end of file" error.
I've seen these in the past, and I know the cause is usually a missing } somewhere or a missing ; after a struct or class definition. However, I've looked over this code carefully and can't for the life of me find any unmatched brackets. Is there anything else that might be causing this error? Can anyone see a problem with the existing code?
Visual Studio is calling out the error for this file specifically, which makes me think the problem is there and not with any of the header files. Am I correct about that, or could there be a problem in one of the custom header files instead?
* socket_win32.c
*
* Copyright 2013-2018 Michael Zillgith
*
* This file is part of libIEC61850.
<rest of header redacted for space>*/
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdbool.h>
#include <stdio.h>
#pragma comment (lib, "Ws2_32.lib")
#include "lib_memory.h"
#include "hal_socket.h"
#include "stack_config.h"
#ifndef __MINGW64_VERSION_MAJOR
struct tcp_keepalive {
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
};
#endif
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
struct sSocket {
SOCKET fd;
uint32_t connectTimeout;
};
struct sServerSocket {
SOCKET fd;
int backLog;
};
struct sHandleSet {
fd_set handles;
SOCKET maxHandle;
};
HandleSet Handleset_new(void)
{
HandleSet result = (HandleSet) GLOBAL_MALLOC(sizeof(struct sHandleSet));
if (result != NULL) {
FD_ZERO(&result->handles);
result->maxHandle = INVALID_SOCKET;
}
return result;
}
void Handleset_reset(HandleSet self)
{
FD_ZERO(&self->handles);
self->maxHandle = INVALID_SOCKET;
}
void Handleset_addSocket(HandleSet self, const Socket sock)
{
if (self != NULL && sock != NULL && sock->fd != INVALID_SOCKET) {
FD_SET(sock->fd, &self->handles);
if ((sock->fd > self->maxHandle) || (self->maxHandle == INVALID_SOCKET)){
self->maxHandle = sock->fd;
}
}
}
int Handleset_waitReady(HandleSet self, unsigned int timeoutMs)
{
int result;
if (self != NULL && self->maxHandle >= 0) {
struct timeval timeout;
timeout.tv_sec = timeoutMs / 1000;
timeout.tv_usec = (timeoutMs % 1000) * 1000;
result = select(self->maxHandle + 1, &self->handles, NULL, NULL, &timeout);
} else {
result = -1;
}
return result;
}
void Handleset_destroy(HandleSet self)
{
GLOBAL_FREEMEM(self);
}
static bool wsaStartupCalled = false;
static int socketCount = 0;
void Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count)
{
struct tcp_keepalive keepalive;
DWORD retVal=0;
keepalive.onoff = 1;
keepalive.keepalivetime = CONFIG_TCP_KEEPALIVE_IDLE * 1000;
keepalive.keepaliveinterval = CONFIG_TCP_KEEPALIVE_INTERVAL * 1000;
if (WSAIoctl(self->fd, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive),
NULL, 0, &retVal, NULL, NULL) == SOCKET_ERROR)
{
if (DEBUG_SOCKET){
printf("WIN32_SOCKET: WSAIotcl(SIO_KEEPALIVE_VALS) failed: %d\n",
WSAGetLastError());
}
}
}
static void setSocketNonBlocking(Socket self)
{
unsigned long mode = 1;
int tcpNoDelay = 1;
if (ioctlsocket(self->fd, FIONBIO, &mode) != 0) {
if (DEBUG_SOCKET){
printf("WIN32_SOCKET: failed to set socket non-blocking!\n");
}
}
/* activate TCP_NODELAY */
setsockopt(self->fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&tcpNoDelay, sizeof(int));
}
static bool prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr)
{
memset((char *) sockaddr , 0, sizeof(struct sockaddr_in));
if (address != NULL) {
struct hostent *server;
server = gethostbyname(address);
if (server == NULL) return false;
memcpy((char *) &sockaddr->sin_addr.s_addr, (char *) server->h_addr, server->h_length);
}
else{
sockaddr->sin_addr.s_addr = htonl(INADDR_ANY);
}
sockaddr->sin_family = AF_INET;
sockaddr->sin_port = htons(port);
return true;
}
static bool wsaStartUp()
{
if (wsaStartupCalled == false) {
int ec;
WSADATA wsa;
if ((ec = WSAStartup(MAKEWORD(2, 0), &wsa)) != 0) {
if (DEBUG_SOCKET)
printf("WIN32_SOCKET: winsock error: code %i\n", ec);
return false;
}
else {
wsaStartupCalled = true;
return true;
}
}
else{
return true;
}
}
static void wsaShutdown()
{
if (wsaStartupCalled) {
if (socketCount == 0) {
WSACleanup();
wsaStartupCalled = false;
}
}
}
ServerSocket TcpServerSocket_create(const char* address, int port)
{
ServerSocket serverSocket = NULL;
int ec;
SOCKET listen_socket = INVALID_SOCKET;
struct sockaddr_in server_addr;
int optionReuseAddr = 1;
if (wsaStartUp() == false){
return NULL;
}
if (!prepareServerAddress(address, port, &server_addr)){
return NULL;
}
listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_socket == INVALID_SOCKET) {
if (DEBUG_SOCKET){
printf("WIN32_SOCKET: socket failed with error: %i\n", WSAGetLastError());
}
wsaShutdown();
return NULL;
}
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&optionReuseAddr, sizeof(int));
ec = bind(listen_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (ec == SOCKET_ERROR) {
if (DEBUG_SOCKET){
printf("WIN32_SOCKET: bind failed with error:%i\n", WSAGetLastError());
}
closesocket(listen_socket);
wsaShutdown();
return NULL;
}
serverSocket = (ServerSocket) GLOBAL_MALLOC(sizeof(struct sServerSocket));
serverSocket->fd = listen_socket;
serverSocket->backLog = 10;
setSocketNonBlocking((Socket) serverSocket);
socketCount++;
return serverSocket;
}
void ServerSocket_listen(ServerSocket self)
{
listen(self->fd, self->backLog);
}
Socket ServerSocket_accept(ServerSocket self)
{
int fd;
Socket conSocket = NULL;
fd = accept(self->fd, NULL, NULL);
if (fd >= 0) {
conSocket = (Socket) GLOBAL_CALLOC(1, sizeof(struct sSocket));
conSocket->fd = fd;
socketCount++;
setSocketNonBlocking(conSocket);
}
return conSocket;
}
void ServerSocket_setBacklog(ServerSocket self, int backlog)
{
self->backLog = backlog;
}
void ServerSocket_destroy(ServerSocket self)
{
closesocket(self->fd);
socketCount--;
wsaShutdown();
GLOBAL_FREEMEM(self);
}
Socket TcpSocket_create()
{
Socket self = NULL;
int sock;
if (wsaStartUp() == false){
return NULL;
}
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock != INVALID_SOCKET) {
self = (Socket) GLOBAL_MALLOC(sizeof(struct sSocket));
self->fd = sock;
self->connectTimeout = 5000;
socketCount++;
}
else {
if (DEBUG_SOCKET)
printf("SOCKET: failed to create socket (error code=%i)\n", WSAGetLastError());
}
return self;
}
void Socket_setConnectTimeout(Socket self, uint32_t timeoutInMs)
{
self->connectTimeout = timeoutInMs;
}
bool Socket_connect(Socket self, const char* address, int port)
{
struct sockaddr_in serverAddress;
fd_set fdSet;
struct timeval timeout;
if (!prepareServerAddress(address, port, &serverAddress)){
return false;
}
setSocketNonBlocking(self);
FD_ZERO(&fdSet);
FD_SET(self->fd, &fdSet);
if (connect(self->fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) == SOCKET_ERROR) {
if (WSAGetLastError() != WSAEWOULDBLOCK){
return false;
}
}
timeout.tv_sec = self->connectTimeout / 1000;
timeout.tv_usec = (self->connectTimeout % 1000) * 1000;
if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) <= 0){
return false;
}
else{
return true;
}
}
//apa+++
/* Portable IPv6/IPv4 version of sockaddr. Based on RFC 2553.
Pad to force 8 byte alignment and maximum size of 128 bytes. */
/*
* Desired design of maximum size and alignment
*/
#ifndef _WS2DEF_
#define _SS_MAXSIZE 128
#define _SS_ALIGNSIZE (sizeof (__int64))
#endif
/*
* Definitions used for sockaddr_storage structure paddings design.
*/
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (short))
#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (short) \
+ _SS_PAD1SIZE \
+ _SS_ALIGNSIZE))
#ifndef _WS2DEF_
struct sockaddr_storage {
short ss_family;
char __ss_pad1[_SS_PAD1SIZE]; /* pad to 8 */
__int64 __ss_align; /* force alignment */
char __ss_pad2[_SS_PAD2SIZE]; /* pad to 128 */
};
#define INET6_ADDRSTRLEN 65
//end apa+++
char* Socket_getPeerAddress(Socket self)
{
struct sockaddr_storage addr;
int addrLen = sizeof(addr);
char addrString[INET6_ADDRSTRLEN + 7];
int addrStringLen = INET6_ADDRSTRLEN + 7;
int port;
bool isIPv6;
char* clientConnection;
getpeername(self->fd, (struct sockaddr*) &addr, &addrLen);
if (addr.ss_family == AF_INET) {
struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &addr;
port = ntohs(ipv4Addr->sin_port);
ipv4Addr->sin_port = 0;
WSAAddressToString((LPSOCKADDR) ipv4Addr, sizeof(struct sockaddr_storage), NULL,
(LPSTR) addrString, (LPDWORD) &addrStringLen);
isIPv6 = false;
}
else if (addr.ss_family == AF_INET6){
struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &addr;
port = ntohs(ipv6Addr->sin6_port);
ipv6Addr->sin6_port = 0;
WSAAddressToString((LPSOCKADDR) ipv6Addr, sizeof(struct sockaddr_storage), NULL,
(LPSTR) addrString, (LPDWORD) &addrStringLen);
isIPv6 = true;
}
else{
return NULL;
}
clientConnection = (char*) GLOBAL_MALLOC(strlen(addrString) + 9);
if (isIPv6){
sprintf(clientConnection, "[%s]:%i", addrString, port);
} else {
sprintf(clientConnection, "%s:%i", addrString, port);
}
return clientConnection;
}
char* Socket_getPeerAddressStatic(Socket self, char* peerAddressString)
{
struct sockaddr_storage addr;
int addrLen = sizeof(addr);
char addrString[INET6_ADDRSTRLEN + 7];
int addrStringLen = INET6_ADDRSTRLEN + 7;
int port;
bool isIPv6;
getpeername(self->fd, (struct sockaddr*) &addr, &addrLen);
if (addr.ss_family == AF_INET) {
struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &addr;
port = ntohs(ipv4Addr->sin_port);
ipv4Addr->sin_port = 0;
WSAAddressToString((LPSOCKADDR) ipv4Addr, sizeof(struct sockaddr_storage), NULL,
(LPSTR) addrString, (LPDWORD) & addrStringLen);
isIPv6 = false;
}
else if (addr.ss_family == AF_INET6) {
struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &addr;
port = ntohs(ipv6Addr->sin6_port);
ipv6Addr->sin6_port = 0;
WSAAddressToString((LPSOCKADDR) ipv6Addr, sizeof(struct sockaddr_storage), NULL,
(LPSTR) addrString, (LPDWORD) & addrStringLen);
isIPv6 = true;
}
else {
return NULL;
}
if (isIPv6){
sprintf(peerAddressString, "[%s]:%i", addrString, port);
} else {
sprintf(peerAddressString, "%s:%i", addrString, port);
}
return peerAddressString;
}
int Socket_read(Socket self, uint8_t* buf, int size)
{
int bytes_read = recv(self->fd, (char*) buf, size, 0);
if (bytes_read == 0){ // peer has closed socket
return -1;
}
if (bytes_read == SOCKET_ERROR) {
if (WSAGetLastError() == WSAEWOULDBLOCK){
return 0;
} else {
return -1;
}
}
return bytes_read;
}
int Socket_write(Socket self, uint8_t* buf, int size)
{
int bytes_sent = send(self->fd, (char*) buf, size, 0);
if (bytes_sent == SOCKET_ERROR) {
int errorCode = WSAGetLastError();
if (errorCode == WSAEWOULDBLOCK){
bytes_sent = 0;
} else {
bytes_sent = -1;
}
}
return bytes_sent;
}
void Socket_destroy(Socket self)
{
if (self->fd != INVALID_SOCKET) {
closesocket(self->fd);
}
socketCount--;
wsaShutdown();
GLOBAL_FREEMEM(self);
}````
The line
#ifndef _WS32DEF_
has no corrsponding #endif
#ifndef _WS2DEF_
struct sockaddr_storage {
short ss_family;
char __ss_pad1[_SS_PAD1SIZE]; /* pad to 8 */
__int64 __ss_align; /* force alignment */
char __ss_pad2[_SS_PAD2SIZE]; /* pad to 128 */
};
#endif
This should work.

Proxy DNS not receiving response

I am creating proxy dns and I recieved query from dig, send it to server but can´t get answer from dns server. I know my code doesn´t look good but I am working on this for hours and still can´t get what is wrong. My program just stuck before second recvfrom. Can someone help me? (btw my OS for this is FreeBSD and I am testing this with 8.8.8.8 dns server)
This is my code:
int main(int argc, char *argv[] )
{
char buf[BUFSIZE];
char serverbuf[BUFSIZE];
int UDPSocket, clientSocket;
int lenght;
int addr_len;
struct addrinfo *clientInfo;
struct addrinfo hintsClient;
struct sockaddr_in serverSocket, clientAddr, serverAddr;
int serverAddrLen = sizeof(serverAddr);
fd_set set, tcpset;
struct timeval tv; // struktura pro timeout
bool end = false;
int m;
TprogParam param = processParams(argc, argv);
if(param.error)
{
printError(EPARAMS);
return ERROR;
}
if(param.help)
{
printHelp();
return EXIT_SUCCESS;
}
memset(&hintsClient, 0, sizeof(struct addrinfo));
hintsClient.ai_family = AF_INET;
hintsClient.ai_socktype = SOCK_DGRAM;
hintsClient.ai_flags = 0;
hintsClient.ai_protocol = IPPROTO_UDP;
int status;
if(param.ipadress[0] == '\0')
{
if((status = getaddrinfo(INADDR_ANY, NULL, &hintsClient, &clientInfo)) != 0)
{
printf("Spatna adresa pro naslouchani");
printError(1);
return ERROR;
}
}
else
{
if((status = getaddrinfo(param.ipadress, "13066", &hintsClient, &clientInfo)) != 0)
{
printf("Spatna adresa pro naslouchani");
printError(1);
return ERROR;
}
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(param.dnsserver);;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = 53;
// vytvorime socket
if((UDPSocket = socket(clientInfo->ai_family, clientInfo->ai_socktype, clientInfo->ai_protocol)) == -1)
{
printf("Nelze vytvorit udp socket");
printError(1);
return ERROR;
}
if((clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("Nelze vytvorit tcp socket");
printError(1);
return ERROR;
}
// Nastavime socket do neblokovaciho rezimu
if(bind(UDPSocket, clientInfo->ai_addr, clientInfo->ai_addrlen) == -1)
{
if (errno != EINPROGRESS)
{
printf("Nelze navazat spojeni pro naslouchani: %d", errno);
return ERROR;
}
}
printf("Poslal jsem zadost o spojeni. Zatimco se spojeni navazuje mohu delat jine veci.\n");
FD_ZERO(&set);
FD_SET(UDPSocket, &set);
tv.tv_sec = 15;
tv.tv_usec = 0;
addr_len = sizeof(struct sockaddr);
while(1)
{
printf("Prijimam pozadavek k vyrizeni.\n");
if ((lenght = recvfrom(UDPSocket, buf, BUFSIZE - 1, 0, (struct sockaddr *)&clientAddr, &addr_len)) == -1)//recv(UDPSocket, buf, BUFSIZE - 1, 0)) == -1)
{
printf("Nejaka chyba pri prijimani dat");
return ERROR;
}
buf[lenght] = '\0';
printf("Prijata nasledujici data od klienta na predklad dns: %s o delce %d \n", buf, lenght);
if((m = sendto(clientSocket, buf, lenght, 0, (struct sockaddr *)&serverAddr, serverAddrLen)) == -1)
{
printf("Problem s odeslanim dat: %d %s", errno, strerror(errno));
return ERROR;
}
if((m = recvfrom(clientSocket, buf, BUFSIZE - 1, 0, (struct sockaddr *)&serverAddr,&serverAddrLen)) == -1)
{
printf("nejaka chyba");
return ERROR;
}
if((lenght = sendto(UDPSocket, buf, lenght, 0,(struct sockaddr *)&clientAddr, lenght)) == -1)
{
printf("Problem s odeslanim dat: errno %d", errno);
return ERROR;
}
}
}
Edit: New code after some fixes:
#include "dns_stat.h"
TprogParam processParams(int argc, char *argv[]) {
TprogParam parInfo =
{
.error = false,
.help = false,
.ipadress[0] = '\0',
.port = 0,
.dnsserver[0] = '\0',
.type = false,
.source = false,
.destination = false,
};
if(argc == 1)
{
parInfo.help = true;
}
else
{
int c;
const char *short_options = ":l:p:s:";
const struct option long_options[] = {
{ "type", 0, NULL, 't' },
{ "source", 0, NULL, 'z' },
{ "destination", 0, NULL, 'd' },
{ NULL, 0, NULL, 0 }
};
while((c = getopt_long_only(argc, argv, short_options, long_options, NULL)) != -1) {
switch (c) {
case 'l':
strcpy(parInfo.ipadress,optarg);
break;
case 'p':
parInfo.port = atoi(optarg);
break;
case 's':
strcpy(parInfo.dnsserver,optarg);//optarg);
//parInfo.dnsserver = strdup(optarg);
break;
case 't':
parInfo.type = true;
break;
case 'z':
parInfo.source = true;
break;
case 'd':
parInfo.destination = true;
break;
case '?':
parInfo.error = true;
break;
default:
printf("default");
parInfo.error = true;
abort();
}
}
}
return parInfo;
}
void printHelp()
{
printf("Napoveda\n");
}
void printError(int ecode)
{
if(ecode<EOK||ecode>EUNKNOWN){
ecode = EUNKNOWN;
}
fprintf(stderr, "%s", ECODEMSG[ecode]);
}
int main(int argc, char *argv[] )
{
char buf[BUFSIZE];
char serverbuf[BUFSIZE];
int UDPSocket, clientSocket;
int lenght;
int addr_len;
struct addrinfo *clientInfo;
struct addrinfo hintsClient;
struct sockaddr_in serverSocket, clientAddr, serverAddr;
int serverAddrLen = sizeof(serverAddr);
fd_set set, tcpset;
struct timeval tv; // struktura pro timeout
bool end = false;
bool end2 = false;
int m;
TprogParam param = processParams(argc, argv);
if(param.error)
{
printError(EPARAMS);
return ERROR;
}
if(param.help)
{
printHelp();
return EXIT_SUCCESS;
}
//printf("type: %d, source: %d, destination: %d\n", param.type, param.source, param.destination);
memset(&hintsClient, 0, sizeof(struct addrinfo));
hintsClient.ai_family = AF_INET;
hintsClient.ai_socktype = SOCK_DGRAM;
hintsClient.ai_flags = 0;
hintsClient.ai_protocol = IPPROTO_UDP;
int status;
if(param.ipadress[0] == '\0')
{
if((status = getaddrinfo(INADDR_ANY, NULL, &hintsClient, &clientInfo)) != 0)
{
printf("Spatna adresa pro naslouchani");
printError(1);
return ERROR;
}
}
else
{
if((status = getaddrinfo(param.ipadress, "13066", &hintsClient, &clientInfo)) != 0)
{
printf("Spatna adresa pro naslouchani");
printError(1);
return ERROR;
}
}
memset(&serverAddr, 0, sizeof(serverAddr));
;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(param.dnsserver);;
serverAddr.sin_port = htons(53);
// vytvorime socket
if((UDPSocket = socket(clientInfo->ai_family, clientInfo->ai_socktype, clientInfo->ai_protocol)) == -1)
{
printf("Nelze vytvorit udp socket");
printError(1);
return ERROR;
}
if((clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("Nelze vytvorit tcp socket");
printError(1);
return ERROR;
}
// Nastavime socket do neblokovaciho rezimu
if(bind(UDPSocket, clientInfo->ai_addr, clientInfo->ai_addrlen) == -1)
{
if (errno != EINPROGRESS)
{
printf("Nelze navazat spojeni pro naslouchani: %d", errno);
return ERROR;
}
}
printf("Poslal jsem zadost o spojeni. Zatimco se spojeni navazuje mohu delat jine veci.\n");
FD_ZERO(&set);
FD_SET(UDPSocket, &set);
tv.tv_sec = 15;
tv.tv_usec = 0;
addr_len = sizeof(struct sockaddr);
while(1)
{
printf("Prijimam pozadavek k vyrizeni.\n");
if ((lenght = recvfrom(UDPSocket, buf, BUFSIZE - 1, 0, (struct sockaddr *)&clientAddr, &addr_len)) == -1)//recv(UDPSocket, buf, BUFSIZE - 1, 0)) == -1)
{
printf("Nejaka chyba pri prijimani dat");
return ERROR;
}
buf[lenght] = '\0';
printf("Prijata nasledujici data od klienta na predklad dns: %s o delce %d \n", buf, lenght);
if((m = sendto(clientSocket, buf, lenght, 0, (struct sockaddr *)&serverAddr, serverAddrLen)) == -1)
{
printf("Problem s odeslanim dat: %d %s", errno, strerror(errno));
return ERROR;
}
printf("tady");
fflush(stdout);
if((m = recvfrom(clientSocket, buf, BUFSIZE - 1, 0, (struct sockaddr *)&serverAddr,&serverAddrLen)) == -1)
{
printf("nejaka chyba");
return ERROR;
}
printf("Prijata nasledujici data od dns serveru: %s o delce %d \n", buf, lenght);
if((lenght = sendto(UDPSocket, buf, lenght, 0,(struct sockaddr *)&clientAddr, addr_len)) == -1)
{
printf("Problem s odeslanim dat: errno %d %s", errno, strerror(errno));
return ERROR;
}
}
}
At least two issues here:
serverAddr.sin_addr.s_addr = inet_addr(param.dnsserver);; /* line 1 */
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* line 2 */
serverAddr.sin_port = 53; /* line 3 */
Line 2 overwrites server address you just translated on line 1. Just remove line 2.
Line 3 needs to change to htons(53) to convert port number to network byte order.

Resources