is there a working vmci example? - sockets

I need a working VMCI socket example that does what UDP does, but without networking. There are many good code fragments in the vmci_sockets.h code, but not a full working template to expand on.
I believe that the server should look as follows:
#include "vmci_sockets.h"
#define BUFSIZE 2048
int main() {
int afVMCI = VMCISock_GetAFValue();
if ((sockfd_dgram = socket(afVMCI, SOCK_DGRAM, 0)) == -1) {
perror("socket");
goto exit;
}
struct sockaddr_vm my_addr = {0};
my_addr.svm_family = afVMCI;
my_addr.svm_cid = VMADDR_CID_ANY;
my_addr.svm_port = VMADDR_PORT_ANY;
if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof my_addr) == -1) {
perror("bind");
goto close;
}
if (getsockname(sockfd, (struct sockaddr *) &my_addr, &svm_size) == -1) {
perror("getsockname");
goto close;
}
if ((numbytes = recvfrom(sockfd, buf, sizeof buf, 0,
(struct sockaddr *) &their_addr, &svm_size)) == -1) {
perror("recvfrom");
goto close;
}
close:
return close(sockfd);
}
and for the client
#include <stdio.h>
#include <string.h>
#include "vmci_sockets.h"
#define BUFSIZE 128
int main() {
int afVMCI = VMCISock_GetAFValue();
int fd;
struct sockaddr_vm addr;
if ((fd = socket(afVMCI, SOCK_DGRAM, 0)) == -1) {
perror("socket");
return 1;
}
addr.svm_family = afVMCI;
addr.svm_cid = VMADDR_CID_ANY;
addr.svm_port = VMADDR_PORT_ANY;
bind(fd, (struct sockaddr *) &addr, sizeof addr);
struct sockaddr_vm serveraddr;
socklen_t svm_size = sizeof serveraddr;
{
int numbytes; char buf[BUFSIZE]; bzero(buf, BUFSIZE);
strcpy(buf, "hello there\n");
if ((numbytes = sendto(fd, buf, BUFSIZE, 0,
(const struct sockaddr *) &serveraddr, svm_size)) == -1) {
perror("sendto error");
goto close;
}
}
close:
close(fd);
VMCISock_ReleaseAFValueFd(fd);
return 0;
}
however, it's not working. there is not much documentation, e.g., how to troubleshoot. there is not information whether one can try both server and client within the same virtual machine for debugging purposes.
I tried to post to the vmware board, sent an email to their support, but no one seems to have a working example. because this is not standard socketry, though it is similar socketry, it is and is not followable.
anyone have a working example?

vmci is apparently not supported for vmplayer or vmware fusion. this is what the vmware support people told me:
I have been checking internally with our development team regarding
your request and incidentally could only generate interest if this was
a situation that is failing with vSphere. The final comment I have is
that we never meant to officially support this for VMware Fusion and
certain dependencies are on internal references only.
Unfortunately, we do not have any such vmci example which can be
shared publicly when it comes to VMware Fusion.

Related

I'm converting ints to chars and trying to send them from a C client to a Python server on another computer. Getting 'send: Bad address'

On one computer with the client (written in C) I get the error send: Bad address when I try to send chars to another computer with a server written in Python. But the address is NOT bad.
If instead of chars I just send a written string, "A string written like this" I can send it just fine to the server and see it print with no problems. So, I don't think there is really a problem with an address.
I have also tried converting the int to a string. I get error when compiling cannot convert string to char. I have tried variations and I can only compile with the client written as it is below.
The client (in C)
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#define ADDR "192.168.0.112"
#define PORT "12003"
void sendall(int socket, char *bytes, int length)
{
int n = 0, total = 0;
while (total < length) {
n = send(socket, bytes + total, total-length, 0);
if (n == -1) {
perror("send");
exit(1);
}
total += n;
}
}
void thesock(char *ADDRf, char *PORTf, char *RAZZstr)
{
struct addrinfo hints = {0}, *addr = NULL;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int status = getaddrinfo(ADDRf, PORTf, &hints, &addr);
if (status != 0) {
std::cerr << "Error message";
exit(1);
}
int sock = -1;
struct addrinfo *p = NULL;
for (p = addr; p != NULL; p = addr->ai_next) {
sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sock == -1) {
continue;
}
if (connect(sock, p->ai_addr, p->ai_addrlen) != -1) {
break;
}
close(sock);
}
if (p == NULL) {
fprintf(stderr, "connect(), socket()\n");
exit(1);
}
sendall(sock, RAZZstr, 12);
close(sock);
}
int main()
{
int someInt = 321;
char strss[12];
sprintf(strss, "%d", someInt);
thesock(ADDR, PORT, strss);
return 0;
}
This last part of the code above is where the chars, or string is entered. It's this part of the code where you can replace strss in thesock with a string written in the strss position "just like this" and it will send to the server on the other computer written in Python. Though, when compiling I do get warnings ISO C++ forbids converting a string constant to ‘char*’.
The server (In Python)
import os
import sys
import socket
s=socket.socket()
host='192.168.0.112'
port=12003
s.bind((host,port))
s.listen(11)
while True:
c, addr=s.accept()
content=c.recv(29).decode('utf-8')
print(content)
This server decodes utf-8. I don't know if I have the option for a different 'decode' here. I don't think Python has 'chars'.
TL;DR: this is unrelated to "address" in terms of IP address but it is about invalid access to a local memory access.
int n = 0, total = 0;
while (total < length) {
n = send(socket, bytes + total, total-length, 0);
total - length is a negative number, i.e. 0-12 = -12 in your case. The third argument of send is of type size_t, i.e. an unsigned integer. The negative number (-12) thus gets cast into an unsigned integer, resulting in a huge unsigned integer.
This causes send to access memory far outside the allocated memory for bytes, hence EFAULT "Bad address".

recvfrom returning errno 14 in debug mode with GDB

I have a code something like this.
where recvfrom works fine if i run the code normally. but when i run the code with GDB, recvfrom doesn't wait for 2 seconds and instantly throwing errno 14.
==
char buf[sizeof(FSME_START)] = { 0 };
/* open socket */
fsm_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fsm_fd < 0)
{
perror("socket");
exit(1);
}
const struct sockaddr_in remote_addr = { .sin_family = AF_INET };
//socklen_t addrlen = sizeof(struct sockaddr);
socklen_t addrlen = sizeof(client_addr);
struct timeval tv = { .tv_sec = 2,
.tv_usec = 0};
/* set initial 1s recv timeout */
int ret = setsockopt(fsm_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
if (ret < 0)
{
perror("setsockopt");
exit(1);
}
while (1)
{
const struct iovec iov = { .iov_base = (void*)FSME_START,
.iov_len = sizeof(FSME_START) };
// Send the START packet (once/sec) to the FSM-E until we get
// receive a START message back based on 1sec timeout set above.
fsm_dp_send(&iov,1,0);
ret = recvfrom(fsm_fd, (char *)buf, MAX_BUFSIZE,
MSG_WAITALL, (struct sockaddr *)&client_addr, &addrlen);
====
I tried passing client_addr and addrlen both parameters as NULL but no success. But strangely this code works if run without GDB.
Any suggestions
looks like there is an error with the size of msg i was passing with recvfrom but it was weird that one version of gdb and and even compiler was hiding this error. This error was visible only with older gdb version. Later on when i passed the correct size of the buffer, it was passing.

Where is wrong with my STUN Binding request

I send udp request to stun.l.google.com:19305, but I don't get any response from google stun server. I omit all of the error check in this piece of code. My program hang in recvfrom.
int stun_socket = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in stun_client;
memset(&stun_client, 0, sizeof(stun_client));
stun_client.sin_family = AF_INET;
stun_client.sin_port = htons(local_port);
int rc = bind(stun_socket, (struct sockaddr *)&stun_client, sizeof(stun_client));
struct sockaddr_in stun_server;
memset(&stun_server, 0, sizeof(stun_server));
stun_server.sin_family = AF_INET;
stun_server.sin_port = htons(remote_port);
inet_pton(AF_INET, server, &stun_server.sin_addr);
typedef struct stun_header_tag {
uint16_t message_type;
uint16_t message_length;
unsigned char transaction_id[16];
} stun_header_t;
stun_header_t header;
header.message_type = htons(0x0001); /* Binding Request */
header.message_length = htons(0);
*(int *)(&header.transaction_id[8]) = 0xFFEEFFEE; /* transaction id in the response should keep consistent with this one */
rc = sendto(stun_socket, (void *)&header, sizeof(header), 0, (struct sockaddr *)&stun_server, sizeof(stun_server));
char response[64];
rc = recvfrom(stun_socket, response, 64, 0, NULL, 0);
I'm guessing you are doing something similar to this or equivalent for sending the data:
sendto(sock, &header, sizeof(header), (sockaddr*)&addr, addrlen);
If that's the case, you likely forgot to convert your message_type value to network byte order (big-endian).
Try this:
header.message_type = htons(0x0001);
But if you want a better solution, and you can use C++, use the client library built into Stuntman. You can generate a binding request as follows with the C++ class, CStunMessageBuilder, declared in the stuncore/stunbuilder.h file.
CStunMessageBuilder builder;
StunTransactionId transId;
builder.AddBindingRequestHeader();
builder.AddRandomTransactionId(&transID);
unsigned char* msg = builder.GetStream().GetDataPointerUnsafe();
size_t len = builder.GetStream().GetSize();
sendto(sock, msg, len, (sockaddr*)&addr, addrlen);

sendto() returning -1 in server

int main()
{
int servsocket,clientsocket;
struct sockaddr_in server,client;
FILE *file;
char filename[100];
char buf[1024];
servsocket=socket(AF_INET,SOCK_DGRAM,0);
server.sin_addr.s_addr=htonl(INADDR_ANY);
server.sin_port=htons(6003);
server.sin_family=AF_INET;
bind(servsocket,(struct sockaddr *) &server,sizeof(server) );
while(1){
int clientsize=0;
printf("Waiting for file requests \n");
recvfrom(servsocket,filename,sizeof(filename),0,(struct sockaddr *)&client,&clientsize);
file=fopen(filename,"r");
int size=0;
do
{
size=fread(buf,1,sizeof(buf),file);
printf("%d bytes read \n",size);
int sentbytes= sendto(servsocket,(const char *)buf,size,0, (struct sockaddr *) &client,sizeof(client));
printf("%d bytes sent ",sentbytes);
}while(size==sizeof(buf));
}
}
I am trying to make a simple program for file transfer using UDP. The problem is that sendto() always returns -1. This is the code for server.
There are quite a few issues with your code. The one you're seeing is that you're not filling in the variable client properly: the clientsize parameter is used for both input and output by the recvfrom system call, so you need to initialise it to the size of the client structure:
int clientsize = sizeof(struct sockaddr_in);
Another issue is that you're not 0-terminating the filename string:
n = recvfrom(...);
filename[n] = '\0';
Finally, you're not testing for errors (bind, recvfrom, sendto, etc.). This will get you into trouble, I promise.

Dispatch source is only called when I do a NSLog() first

I am trying to use grand central dispatch in conjunction with bsd sockets to send an icmp ping. I add DISPATCH_SOURCE_TYPE_WRITE and DISPATCH_SOURCE_TYPE_READ as dispatch sources to read and write async.
So this is the method were I create the bsd socket and install the dispatch sources:
- (void)start
{
int err;
const struct sockaddr * addrPtr;
assert(self.hostAddress != nil);
// Open the socket.
addrPtr = (const struct sockaddr *) [self.hostAddress bytes];
fd = -1;
err = 0;
switch (addrPtr->sa_family) {
case AF_INET: {
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
if (fd < 0) {
err = errno;
}
} break;
case AF_INET6:
assert(NO);
// fall through
default: {
err = EPROTONOSUPPORT;
} break;
}
if (err != 0) {
[self didFailWithError:[NSError errorWithDomain:NSPOSIXErrorDomain code:err userInfo:nil]];
} else {
dispatch_source_t writeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, fd, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(writeSource, ^{
abort(); // testing
// call call method here to send a ping
});
dispatch_resume(writeSource);
//NSLog(#"testout");
dispatch_source_t readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(readSource, ^{
unsigned long bytesAvail = dispatch_source_get_data(readSource);
NSLog(#"bytes available: %lu", bytesAvail);
});
dispatch_resume(readSource);
}
}
You see the //NSLog(#"testout");? The funny thing is that the write block is only called when the //NSLog(#"testout"); is NOT commented out. This is very odd. I didn't test the read callback. The sending needs to be working first.
So what is going on here?
There are kind of a bunch of things missing here. I'm not sure exactly which one is causing the weird behavior, but when I do all of the missing things, it seems to work "as expected" and my write event handler is called reliably and repeatedly. In general, there are a bunch of things you need to do when setting up a socket like this before passing it off to GCD. They are:
Create the socket
Bind it to a local address (missing in your code)
Set it to non-blocking (missing in your code)
Here is a little example I was able to put together in which the write handler gets called repeatedly, as expected:
int DoStuff()
{
int fd = -1;
// Create
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket");
return 0;
}
// Bind
struct sockaddr_in *localAddressPtr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
memset((char *)localAddressPtr, 0, sizeof(*localAddressPtr));
localAddressPtr->sin_family = AF_INET;
localAddressPtr->sin_addr.s_addr = htonl(INADDR_ANY);
localAddressPtr->sin_port = htons(0);
if (bind(fd, (struct sockaddr *)localAddressPtr, sizeof(*localAddressPtr)) < 0) {
perror("bind failed");
return 0;
}
// Set non-blocking
int flags;
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
flags = 0;
if (-1 == fcntl(fd, F_SETFL, flags | O_NONBLOCK))
{
perror("Couldnt set non-blocking");
return 0;
}
// Do a DNS lookup...
struct hostent *hp;
struct sockaddr_in *remoteAddressPtr = malloc(sizeof(struct sockaddr_in));
// Fill in the server's address and data
memset((char*)remoteAddressPtr, 0, sizeof(*remoteAddressPtr));
remoteAddressPtr->sin_family = AF_INET;
remoteAddressPtr->sin_port = htons(12345);
// Look up the address of the server by name
const char* host = "www.google.com";
hp = gethostbyname(host);
if (!hp) {
fprintf(stderr, "could not obtain address of %s\n", host);
return 0;
}
// Copy the host's address into the remote address structure
memcpy((void *)&remoteAddressPtr->sin_addr, hp->h_addr_list[0], hp->h_length);
dispatch_source_t writeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, fd, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(writeSource, ^{
// Send message
const char* my_message = "the only thing we have to fear is fear itself.";
unsigned long len = strlen(my_message);
if (sendto(fd, my_message, len, 0, (struct sockaddr *)remoteAddressPtr, sizeof(*remoteAddressPtr)) != len) {
perror("sendto failed");
dispatch_source_cancel(writeSource);
}
});
dispatch_source_set_cancel_handler(writeSource, ^{
close(fd);
free(localAddressPtr);
free(remoteAddressPtr);
});
dispatch_resume(writeSource);
return 1;
}
NB: There's no way to dispose of the writeSource in my example without there being an error in a send operation. It's a trivial example...
My general theory on why NSLog triggers the handler to fire in your case, is that it keeps execution at or below that stack frame long enough for the background thread to come around and call the handler, but without that NSLog, your function returns, and something has a chance to die before the handler can get called. In fact, if you're using ARC it's probably the writeSource itself that is getting deallocated, since I don't see you making a strong reference to it anywhere outside the scope of this function. (My example captures a strong reference to it in the block, thus keeping it alive.) You could test this in your code by stashing a strong reference to writeSource.
I found the error:
In newer SDKs dispatch sources are subject to automatic reference counting despite the fact that they are no Objective-C objects.
So when the start method is over ARC disposes the dispatch source and they never get called.
NSLog delays the end of the start method in a way that the dispatch source triggers before the source gets disposed.