Unused variable warning when the variable is used - c

I don't understand why I am getting unused variable warnings for 'version' and 'service' in the following c code. I'm also being told the variable bundle is uninitialised when I have initialised it as far as I can tell. Any insight would be appreciated:
int main() {
int fd = socket(AF_INET, /* network versus AF_LOCAL */
SOCK_STREAM, /* reliable, bidirectional, arbitrary payload size */
0); /* system picks underlying protocol (TCP) */
if (fd < 0) report("socket", 1); /* terminate */
/* bind the server's local address in memory */
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr)); /* clear the bytes */
saddr.sin_family = AF_INET; /* versus AF_LOCAL */
saddr.sin_addr.s_addr = htonl(INADDR_ANY); /* host-to-network endian */
saddr.sin_port = htons(80); /* for listening */
if (bind(fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
report("bind", 1); /* terminate */
/* listen to the socket */
if (listen(fd, 20) < 0) /* listen for clients, up to MaxConnects */
report("listen", 1); /* terminate */
spc_krb5bundle_t *bundle;
bundle->ctx = NULL;
bundle->auth_ctx = NULL;
bundle->ticket = NULL;
char* service="krbtgt";
char* version="1";
krb5_error_code spc_krb5_server(int fd, spc_krb5bundle_t *bundle, char *service, char *version);
}
Thank-you.

This line is a function prototype.
krb5_error_code spc_krb5_server(int fd, spc_krb5bundle_t *bundle, char *service, char *version);
You want:
spc_krb5_server(fd, bundle, service, version);

Related

UDP multicast receives 2^24 bytes of data which should be impossible

have a stand alone PC running VS6 on WinXP - yes ancient technology.
I am porting a C code app from Linux.
Stuck on multicast problem
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h> /* for printf(), fprintf() */
#include <conio.h>
#include <winsock.h> /* for socket(),... */
#include <stdlib.h> /* for exit() */
#define MAXRECVSTRING 255 /* Longest string to receive */
int main(int argc, char* argv[])
{
char msg[100];
char loopchar = 0;
int iOptVal = 0;
char iOptVal2 = 1;
int iLenOptVal = sizeof(int);
int result = -1;
int retval = -1;
int set_option_on = 1;
int sock; /* Socket */
struct sockaddr_in multicastAddr; /* Multicast Address */
char *multicastIP; /* IP Multicast Address */
unsigned short multicastPort; /* Port */
char recvString[MAXRECVSTRING+1]; /* Buffer for received string */
unsigned int recvStringLen; /* Length of received string */
struct ip_mreq multicastRequest; /* Multicast address join structure */
WSADATA wsaData; /* Structure for WinSock setup communication */
if (argc != 3) /* Test for correct number of arguments */
{
fprintf(stderr,"Usage: %s <Multicast IP> <Multicast Port>\n", argv[0]);
exit(1);
}
multicastIP = argv[1]; /* First arg: Multicast IP address (dotted quad) */
//WW Silversilsied //WW SilversilsiedmulticastIP = inet_addr("224.000.010.101"); /* First arg: Multicast IP address (dotted quad) */
//multicastIP = inet_addr("224.000.010.101"); /* First arg: Multicast IP address (dotted quad) */
multicastPort = atoi(argv[2]);/* Second arg: Multicast port */
//multicastPort = 6600);/* Second arg: Multicast port */
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
{
fprintf(stderr, "WSAStartup() failed");
exit(1);
}
/* Create a best-effort datagram socket using UDP */
if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
printf("\nsocket() failed - error = %d\n", sock);
}
/* Construct bind structure */
memset(&multicastAddr, 0, sizeof(multicastAddr)); /* Zero out structure */
multicastAddr.sin_family = AF_INET; /* Internet address family */
multicastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
multicastAddr.sin_port = htons(multicastPort); /* Multicast port */
/* Bind to the multicast port */
retval = bind(sock, (struct sockaddr *) &multicastAddr, sizeof(multicastAddr));
if (retval < 0)
{
printf("\nbind() failed - error = %d\n", retval);
}
#if 0
/* Specify the multicast group */
multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastIP);
/* Accept multicast from any interface */
multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
/* Join the multicast address */
//if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multicastRequest, sizeof(multicastRequest)) < 0)
result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&set_option_on, sizeof(set_option_on));
if (result < 0)
{
printf("\n setsockopt() failed");
perror(" setsockopt ");
}
/* Receive a single datagram from the server */
while(1)
{
if ((recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0)) < 0)
{
printf("\nrecvfrom() failed");
}
Sleep(1000);
}
#else
strcpy(msg,"default test message");
struct sockaddr_in address1;
int len;
int bytes_sent = -1;
memset(&address1, 0, sizeof(address1));
address1.sin_family = AF_INET;
address1.sin_port = multicastPort;
address1.sin_addr.s_addr = inet_addr(multicastIP);
//msg = "abcdefghijklmnopqrstuvwxyz";
//socklen_t len;
//size = strlen(msg);
if ((recvStringLen = recvfrom(sock, recvString, 1024, 0, (struct sockaddr*)&address1, &len)) < 0)
{
printf("\nrecvfrom() failed ");
perror(" recvfrom ");
}else{
recvString[recvStringLen] = '\0';
printf("Received: %d bytes %s\n", recvStringLen,recvString); /* Print the received string */
perror(" received from ");
}
bytes_sent = sendto(sock,
msg,
sizeof(msg),
0,
(struct sockaddr*)&address1,
sizeof(address1));
printf("bytes sent = %d \n", bytes_sent);
printf("size of msg = %d \n ", sizeof(msg));
perror( "sendto ");
#endif
getch();
closesocket(sock);
WSACleanup(); /* Cleanup Winsock */
exit(0);
return 0;
}
When I single step through, I get a successful socket creation and valid socket descriptor.
I get a successful bind, at which point the port shows up as udp when I do a cmd line netstat -p UDP -a
setsockopt also completes without error.
When I step through the recvfrom it receives 2^24 bytes all of which are the same -52
The machine is stand alone, not on a network.
recvString is 256 bytes long, but your recvFrom() is asking for up to 1024 bytes.

TCP/IP in C not working

I am having trouble getting my TCP/IP connection between my client and server working.
Here is the server code -
int main() {
int servSock; /* Socket descriptor for server */
int clntSock; /* Socket descriptor for client */
unsigned short echoServPort; /* Server port */
struct sockaddr_in echoServAddr; /* Local address */
struct sockaddr_in echoClntAddr; /* Local address */
pid_t processID; /* Process ID from fork()*/
unsigned int childProcCount = 0; /* Number of child processes */
unsigned int clntLen;
unsigned int recvMsgSize;
echoServPort = 22;
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
printf("Socket failed");
}
echoServAddr.sin_family = AF_INET; //Internet address family
echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); //Any incoming interface
echoServAddr.sin_port = htons(echoServPort); // Local port
if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0){
printf("bind failed");
}
if (listen(servSock, MAXPENDING) < 0){
printf("listen() failed");
}
clntLen = sizeof(echoClntAddr);
if ((clntSock=accept(servSock,(struct sockaddr *)&echoClntAddr,&clntLen))<0){
printf("accept() failed");
}
if ((recvMsgSize = recv(clntSock, buf, 1024, 0)) < 0){
printf("recv() failed");
}
/* Send received string and receive again until end of transmission */
while (recvMsgSize > 0) { /* zero indicates end of transmission */
printf("%d", recvMsgSize);
if (send(clntSock, buf, recvMsgSize, 0) != recvMsgSize){
//printf(“send() failed”);
}
if ((recvMsgSize = recv(clntSock, buf, 1024, 0)) < 0){
//printf(“recv() failed”);
}
}
sleep(60);
}
}
return EXIT_SUCCESS;
}
And the client code, which is a CGI application.
int main(void) {
int servSock; /* Socket descriptor for server */
int clntSock; /* Socket descriptor for client */
unsigned short echoServPort; /* Server port */
struct sockaddr_in echoServAddr; /* Local address */
struct sockaddr_in echoClntAddr; /* Local address */
struct sockaddr_in {
__uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
/*pid_t processID; Process ID from fork()
unsigned int childProcCount = 0; Number of child processes
unsigned int clntLen;*/
//char echoservIP = "10.0.0.2";
printf("Content-type: text/html\n\n");
puts("<HTML>");
puts("<BODY>");
echoServPort = 22;
servSock = 22;
clntSock = 22;
puts("<br>");
if ((clntSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
printf("socket() failed");
}
echoServAddr.sin_family = AF_INET; //Internet address family
echoServAddr.sin_addr.s_addr = inet_addr("10.0.0.2"); //Server IP address
echoServAddr.sin_port = htons(echoServPort); //Server port
echoClntAddr.sin_addr.s_addr = inet_addr("10.0.0.1");
if (connect(clntSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0){
printf("connect() failed\n");
}
int clntLen;
clntLen = sizeof(echoClntAddr);
if ((clntSock=accept(servSock,(struct sockaddr *)&echoClntAddr,&clntLen))<0){
printf("accept() failed\n");
}
char echoString[4] = "helo";
int echoStringLen;
echoStringLen = strlen(echoString); //Determine input length
//Send the string to the server
if (send(clntSock, echoString, echoStringLen, 0) != echoStringLen){
printf("send() sent a different number of bytes than expected");
}
puts("<p>Hello <b>CGI</b</p>");
puts("</BODY>");
puts("</HTML>");
return EXIT_SUCCESS;
}
When debugging, the problem occurs on the client side at the line
if ((clntSock=accept(servSock,(struct sockaddr
*)&echoClntAddr,&clntLen))<0){
printf("accept() failed\n");
}
And at
if(send(clntSock, echoString, echoStringLen, 0) != echoStringLen){
printf("send() sent a different number of bytes than expected");
}
I get the output
<HTML>
<BODY>
<br>
accept() failed
send() sent a different number of bytes than expected<p>Hello
<b>CGI</b</p>
Need help fixing this!, thanks.
You don't need to call accept() on the client - you just need to connect.
And
char echoString[4] = "helo";
is wrong. It's not NUL-terminated. Just do
char echoString[] = "helo";
If accept fails you shouldn't be proceeding with other operations on socket like recv. TCP connections is not in place for you to proceed in data exchange between server and client. You need to handle error conditions with out fail.
On the client side you have a custom error message on send. That does not help. Usually, partial sends are not common. Hence your print `sent a different number of bytes than expected' can be misleading. You need to find the real reason.
Calling accept in client code is not needed. Its the server which accepts and clients the ones which connect
Use errno and perror like - perror("Accept Failed") on ALL of your system calls for easier debugging and remove custom prints

Simple Socket Listener and Threads Memory Leak

I have a simple C program that's supposed to listen for connections and start a new thread for each client that connects. The thread simply prints what messages it receives (for now). I followed two tutorials while making this.
It works, but I tried connecting and disconnecting repeatedly with netcat without sending any messages. Each time I connect, the program takes 8KB of memory, but it only releases 4KB when I disconnect. But I can't find the cause of the leak. It ends the thread and closes the socket every time the user disconnects. Here is all of the code involved:
void* clientFunction(void* arg) {
char receiveBuffer[RECEIVE_BUFFER_SIZE];
long receiveSize;
int clntSocket = * ((int*) arg);
while (true) {
//receive messages
receiveSize = recv(clntSocket, receiveBuffer, RECEIVE_BUFFER_SIZE, 0);
if (receiveSize <= 0) {
close(clntSocket);
return NULL;
}
printf("Received message: %s", receiveBuffer);
memset(&receiveBuffer, 0, sizeof(receiveBuffer));
}
return 0;
}
int main(int argc, const char * argv[]) {
//FOR LISTENING SOCKET =====
int servSock; /* Socket descriptor for server */
int clntSock; /* Socket descriptor for client */
struct sockaddr_in serverAddress; /* Local address */
struct sockaddr_in clientAddress; /* Client address */
unsigned int clntLen; /* Length of client address data structure */
// =======
/* Create socket for incoming connections */
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
printf("Socket creation failed!\n");
return SOCKET_ERROR;
}
memset(&serverAddress, 0, sizeof(serverAddress)); /* Zero out structure */
serverAddress.sin_family = AF_INET; /* Internet address family */
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
serverAddress.sin_port = htons(PORT); /* Local port */
if (bind(servSock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) {
printf("Socket binding failed!\n");
return SOCKET_ERROR;
}
if (listen(servSock, MAXPENDING) < 0) {
printf("Socket listening failed!\n");
return SOCKET_ERROR;
}
isListening = true;
int* arg = &clntSock;
while (isListening) { //should have a timer?
/* Set the size of the in-out parameter */
clntLen = sizeof(clientAddress);
/* Wait for a client to connect */
if ((clntSock = accept(servSock, (struct sockaddr *) &clientAddress, &clntLen)) >= 0) { //??????
/* clntSock is connected to a client! */
pthread_t clientThread;
pthread_create(&clientThread, NULL, &clientFunction, (void*) arg);
}
}
return 0;
}
I put in pthread_detach(pthread_self()) right after the socket closing line, and it doesn't have the problem anymore. – sudo

C - server client multithreaded pthread_create failing

im writing a multithreaded server, how ever i have tried to debug this but for some reason it doesn't actually go into the client thread called by pthread_create(), bottom of main. Any idea why pthread_create() is failing ?
Also i was wondering if it would be a good idea to send a struct to the client and the client send a struct back to the server as the main communication between the server and client? or should send() and recv() be a better way to implement?
int main(int argc, char* argv[])
{
int fdServer;
int accept_fd;
int optVal = 1;
struct sockaddr_in fromAddr;
struct sockaddr_in serverAddr;
struct pollfd* pServerPollFd;
pthread_t threadId;
socklen_t fromAddrSize;
/*
* Check user input and assign values
*/
if(argc != 4)
errorServer(WRONG_CLI);
char* greeting = calloc(100,sizeof(char*));
char* file_name = calloc(100,sizeof(char*));
greeting = argv[2];
file_name = argv[3];
/*
* Check pthread_key_create != 0 -> ERROR
*/
if(pthread_key_create(&threadSpecificKey, dataDestructor))
errorServer(SYSTEM_ERROR);
int port_num = atoi(argv[1]);
if(!((port_num <= 65535)&&(1<=port_num)))
errorServer(INVALID_PORT);
/*
* Set up the server socket
*/
fdServer = socket(AF_INET, SOCK_STREAM, 0);
if(fdServer < 0)
errorServer(SYSTEM_ERROR);
if(setsockopt(fdServer, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) < 0)
errorServer(SYSTEM_ERROR);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port_num);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(fdServer, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr_in)) < 0)
errorServer(PORT_ERROR);
/*
* Setup poll pool
*/
pMessageBuffer = fifo_buffer_create(-1);
poll_pool* pPool = poll_pool_create(MAX_CONNECTIONS + 1);
pServerPollFd = poll_pool_allocate(pPool, fdServer);
pServerPollFd->events |= POLLIN;
int flags = fcntl(fdServer, F_GETFL);// Get the file access mode and the file status flags;
if(fcntl(fdServer, F_SETFL, flags | O_NONBLOCK) == -1)// Set the file descriptor flags to the value specified by 3rd arg.
errorServer(SYSTEM_ERROR);
if(listen(fdServer, 4) != 0)//Allow only 4 connections to the server
errorServer(SYSTEM_ERROR);
while(1) {
fromAddrSize = sizeof(struct sockaddr_in);
/* Block, waiting for a connection request to come in and accept it.
* fromAddr structure will get populated with the address of the client
*/
while((accept_fd = accept(fdServer, (struct sockaddr*)&fromAddr, &fromAddrSize)) != -1){
printf("Someone connected \n");
client_connection *pClientConnection = client_connection_create(accept_fd);
client_details *pClientDetails = client_details_create();
client_session *pClientSession = client_session_create(pClientConnection,pClientDetails);
pthread_mutex_lock(&game_state_mutex);
//SEARCH THE LINKEDLIST FOR THE GAME NAME - IF FALSE CREATE NEW LINKED ELEMENT
C_lst requestedGame;
clst_init(&requestedGame,NULL);
clst_insert_next(&requestedGame,NULL,pClientSession);
pthread_mutex_unlock(&game_state_mutex);
write(accept_fd, greeting, strlen(greeting));
/* Start a thread to deal with client communication - pass the
* connected file descriptor as the last argument.
*/
pthread_create(&threadId, NULL, client_thread, (void*)pClientSession);
pthread_detach(threadId);
}
}
free(greeting);
free(file_name);
return 0;
}
And this is the beginning of the client_thread
void * client_thread(void* arg)
{
ssize_t numBytesRead;
char buffer[MAXBUFFER];
client_session* pClientSession = (client_session*)arg;
if(pthread_setspecific(threadSpecificKey, pClientSession))
errorServer(SYSTEM_ERROR);
/* below read fails because of the nonblocking fdServer from fnctl*/
while((numBytesRead = read(fd,buffer,MAXBUFFER))>0){
//loop code here
}
Why you not checked for pthread_create return value and not print corresponding error message?
s = pthread_create(...);
if (s != 0) {
errno = s;
perror("pthread_create");
exit(EXIT_FAILURE);
}
Source: pthread_create(3)
UPD. Also, for socket setting you can try getaddrinfo(3) instead of doing all by hand: http://www.beej.us/guide/bgnet/output/html/multipage/syscalls.html#getaddrinfo
UPD 2. What do you mean by 'sending struct'?

Sending/receiving weird data

Im sending data on network via sockets like this: (broadcast)
void sendBroad(char *dstIP, char *localIP, char *localMAC)
{
int sock; /* Socket */
struct sockaddr_in broadcastAddr; /* Broadcast address */
int broadcastPermission; /* Socket opt to set permission to broadcast */
unsigned int dataLen;
char data[100]={0};
strcat(data, localIP);
strcat(data, " ");
strcat(data, localMAC);
strcat(data, " ");
/* Create socket for sending/receiving datagrams */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
perror("socket() failed");
/* Set socket to allow broadcast */
broadcastPermission = 1;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission,
sizeof(broadcastPermission)) < 0)
perror("setsockopt() failed");
/* Construct local address structure */
memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */
broadcastAddr.sin_family = AF_INET; /* Internet address family */
broadcastAddr.sin_addr.s_addr = inet_addr(dstIP); /* Broadcast IP address */
broadcastAddr.sin_port = htons(BroadcastPort); /* Broadcast port */
dataLen = strlen(data);
int j;
for (j=0; j<1; j++) /* 3krat a dost */
{
/* Broadcast localIP in datagram to clients */
if (sendto(sock, data, dataLen, 0, (struct sockaddr *)
&broadcastAddr, sizeof(broadcastAddr)) != dataLen)
perror("sendto() sent a different number of bytes than expected");
}
/* NOT REACHED */
}
but I always get some weird chars in the begining when receiving, like:
X.?192.168.....
When I try to send this data 6 times, just once I get data starting with 192..., other 5 strings starts with those weird chars. Any idea what is happening here?
Thanks
char data[100]; is not initialized. Accordingly, you are concatenating to the end of some undefined garbage, not to the end of an empty string. This is obviously undefined behaviour as it is not guaranteed that a '\0' appears anywhere within the reserved space (to say nothing of the fact that it's just plain undefined behaviour and the compiler may actually do what it wishes if/when it detects this).
char data[100] = {0}; should do the trick.

Resources