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;
}
Related
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);
}
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;
}
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.
Im trying to create connection between 2 clients via a server. In this program, client sends a message to the server and server post it to the target client. But there is a little problem between this operation. Transmitter one cannot send another message before it receive some message or receiver one cannot see the received message before send a message. Video should explain better.
You can find scanf function in below of client.c codes
CLIENT
//
// Created by berkin on 18.12.2016.
//
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include <string.h>
#include <zconf.h>
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in server;
char message[2000], server_reply[2000];
//Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8888);
//Connect to remote server
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("Connect failed. Error");
return 1;
}
puts("Connected to server\n");
//keep communicating with server
while (1) {
printf("> ");
scanf("%[^\n]%*c", message);
fflush(stdin);
//Send some data
if (send(sock, message, strlen(message)+1, 0) < 0) {
puts("Send failed");
return 1;
}
if (recv(sock, server_reply, 2000, 0) < 0) {
puts("recv failed");
break;
}
//Receive a reply from the server
printf ("\033[32;1m %s \033[0m\n",server_reply);
}
close(sock);
return 0;
}
SERVER
#include<stdio.h>
#include<string.h> // for strlen
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include<unistd.h> // for write
#include<pthread.h> // for threading, link with lpthread
#include "split.h"
#define MAX_CLIENT_NUMBER 100
void *connection_handler(void *);
struct User {
char userName[10];
int clientSocketNo;
};
unsigned int clientNumber = 0;
unsigned int userArrayIndex = 0;
struct User users[MAX_CLIENT_NUMBER];
//FOR GETUSERS COMMAND
void getUsers(int socketNumber) {
char *userString = malloc(100);
if (users[0].userName != NULL) {
strcpy(userString, users[0].userName);
strcat(userString, ",");
} else {
return;
}
for (int i = 1; i < userArrayIndex; ++i) {
strcat(userString, users[i].userName);
strcat(userString, ",");
}
write(socketNumber, userString, strlen(userString) + 1);
}
//AFTER LOGIN COMMAND, ADD TO THE ARRAY
void addUserToArray(char userName[10], int socketNumber) {
printf("Client logged in as %s\n", userName);
strcpy(users[userArrayIndex].userName, userName);
users[userArrayIndex].clientSocketNo = socketNumber;
userArrayIndex++;
}
//LOGIN COMMAND
void loginUser(char userName[10], int socketNumber) {
char *message = "login successful";
write(socketNumber, message, strlen(message) + 1);
addUserToArray(userName, socketNumber);
}
//SEND MESSAGE IF USER FOUND
void sendMessage(struct User user, char *message){
write(user.clientSocketNo,message,strlen(message) + 1);
}
//SEARCH USER FROM ARRAY
struct User searchUser(char searchName[10]){
for (int i = 0; i < userArrayIndex; ++i) {
if(strcmp(users[i].userName,searchName) == 0){
return users[i];
}
}
}
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
char receivedMessage[2000]; //client's message
int readControl;
int parsedItemNumber = 0;
int sock = *((int *) socket_desc);
while ((readControl = recv(sock, receivedMessage, 2000, 0)) > 0) {
char *parsedCommand[50]; //parsedClientMessage
parsedItemNumber = parsing(parsedCommand, receivedMessage, " ");
if (strcmp(parsedCommand[0], "login") == 0) {
loginUser(parsedCommand[1], sock);
}
else if (strcmp(parsedCommand[0], "getusers") == 0) {
getUsers(sock);
}
else if (strcmp(parsedCommand[0], "exit") == 0) {
close(sock);
return 0;
}
else{
if(parsedCommand[0] != NULL){
struct User find = searchUser(parsedCommand[0]);
if(find.userName != NULL){
char *message = malloc(2000);
if(parsedCommand[1] != NULL){
strcpy(message,parsedCommand[1]);
strcat(message," ");
}
for (int i = 2; i < parsedItemNumber; ++i) {
strcat(message,parsedCommand[i]);
strcat(message," ");
}
sendMessage(find,message);
}
else{
perror("Your input was wrong");
}
}
}
}
if (readControl == 0) {
puts("Client disconnected");
clientNumber--;
fflush(stdout);
} else if (readControl == -1) {
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
int main(int argc, char *argv[]) {
int socket_desc, new_socket, c, *new_sock;
struct sockaddr_in server, client;
//Create Socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
puts("Could not create socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if (bind(socket_desc, (struct sockaddr *) &server, sizeof(server)) < 0) {
puts("Binding failed");
return 1;
}
listen(socket_desc, 3);
puts("Server started");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &c)) &&
clientNumber < MAX_CLIENT_NUMBER) {
pthread_t sniffer_thread[MAX_CLIENT_NUMBER];
new_sock = malloc(1);
*new_sock = new_socket;
if (pthread_create(&sniffer_thread[clientNumber], NULL, connection_handler,
(void *) new_sock) < 0) {
perror("Could not create thread");
return 1;
} else {
clientNumber++;
}
puts("Client connected");
}
if (new_socket < 0) {
perror("accept failed");
return 1;
}
return 0;
}
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.