ICMP recvfrom function always receive data even though the destination was shutdown - ping

I wrote a program in C to ping a machine and receive the echo from that machine to detect if the machine is still alive. My code as following please:
#define PING_PKT_S 64
#define PORT_NO 0
#define PING_SLEEP_RATE 1000000
#define RECV_TIMEOUT 1
int pingloop=1;
struct ping_pkt {
struct icmphdr hdr;
char msg[PING_PKT_S-sizeof(struct icmphdr)];
};
unsigned short checksum(void *b, int len) {
unsigned short *buf = b;
unsigned int sum=0;
unsigned short result;
for ( sum = 0; len > 1; len -= 2 )
sum += *buf++;
if ( len == 1 )
sum += *(unsigned char*)buf;
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
result = ~sum;
return result;
}
//to check if this machine is actively working
int isActiveNow(){
const char *pre = "161.";
char *prefixArr[] = {pre};
char myIp[64];
memset(myIp, 0, sizeof(myIp));
get_local_ip(myIp, prefixArr);
printf("---isActiveNow:%s\n",myIp);
if(myIp[0]=='\0'){
printf("Not Active Now!\n");
return 0;
}
return 1;
}
void intHandler(int dummy) {
pingloop=0;
}
long current_timestamp() {
struct timeval te;
gettimeofday(&te, NULL);
long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000;
return milliseconds;
}
void display(void *buf, int bytes){
int i;
struct iphdr *ip = buf;
struct icmphdr *icmp = buf+ip->ihl*4;
printf("---------------------Start Display\n");
for ( i = 0; i < bytes; i++ ){
printf("%c", ((unsigned char*)buf)[i]);
}
printf("---------------------End Display\n");
}
int failedNum = 0;
// make a ping request
void send_ping(int ping_sockfd, char *ping_ip) {
int ttl_val=64, msg_count=0, i, addr_len, msg_received_count=0;
struct ping_pkt pckt;
struct sockaddr_in r_addr;
struct timespec time_start, time_end;
// set socket options at ip to TTL and value to 64,
if (setsockopt(ping_sockfd, SOL_IP, IP_TTL, &ttl_val, sizeof(ttl_val)) != 0) {
printf("Setting socket options to TTL failed!\n");
return;
}else{
printf("\nSocket set to TTL..\n");
}
// send icmp packet in an infinite loop
while(pingloop) {
sleep(2);
if(isActiveNow()){
printf("--current is active!");
continue;
}
//filling packet
bzero(&pckt, sizeof(pckt));
pckt.hdr.type = ICMP_ECHO;
pckt.hdr.un.echo.id = getpid();
for ( i = 0; i < 10; i++ ){
pckt.msg[i] = 'w';
}
pckt.msg[i] = 0;
pckt.hdr.un.echo.sequence = msg_count++;
pckt.hdr.checksum = checksum(&pckt, sizeof(pckt));
long s1 = current_timestamp();
struct hostent *hostentObj;
hostentObj = gethostbyname(ping_ip);
struct sockaddr_in ping_addr;
ping_addr.sin_port = 0;
ping_addr.sin_family = hostentObj->h_addrtype;
ping_addr.sin_addr.s_addr = *(long*) hostentObj->h_addr;
//Using synchronize
if ( sendto(ping_sockfd, &pckt, sizeof(pckt), 0, (struct sockaddr*) &ping_addr, sizeof(ping_addr)) <= 0) {
printf("\nPacket Sending Failed!\n");
}
struct timeval tv_out;
tv_out.tv_sec = 10;
tv_out.tv_usec = 0;
// setsockopt(ping_sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv_out, sizeof tv_out);
struct sockaddr_in myAddr;
unsigned char buf[1024];
int len=sizeof(myAddr);
bzero(buf, sizeof(buf));
struct ping_pkt pckt2;
int bytes = recvfrom(ping_sockfd, &pckt2, sizeof(pckt2), 0, (struct sockaddr*)&myAddr, &len);
printf("---------------------bytes len:%d\n",bytes);
if ( bytes > 0 ){
display(&pckt2, bytes);
long s2 = current_timestamp();
printf("from %s msg_seq=%d ttl=%d rtt = %ld ms. pckt.hdr.type=%d \n", ping_ip, msg_count,ttl_val, (s2-s1), pckt.hdr.type);
}else{
printf("-------NO RESPONSE!!!!!!\n");
failedNum++;
//maximum detected failed number is 10
if(failedNum>3){
printf("--The other server dead!!!\n");
}
}
}
}
bool prefix(const char *pre, const char *str){
return strncmp(pre, str, strlen(pre)) == 0;
}
void get_local_ip(char *pubIp, char *prefixArr[]){
char *ip;
int fd, intrface, retn = 0;
struct ifreq buf[INET_ADDRSTRLEN];
struct ifconf ifc;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0){
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (caddr_t)buf;
if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc)){
intrface = ifc.ifc_len/sizeof(struct ifreq);
while (intrface-- > 0){
if (!(ioctl(fd, SIOCGIFADDR, (char *)&buf[intrface]))){
ip=(inet_ntoa(((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr));
int len = 0,i = 0;
len = sizeof(prefixArr) / sizeof(*prefixArr);
for (i = 0; i < len; i++) {
if(prefix(prefixArr[i],ip)){
strcpy(pubIp,ip);
return;
}
}
}
}
}
close(fd);
}
}
// Driver Code
int main(int argc, char *argv[]){
int sockfd;
char *pingIp;
char *prefixArr[] = { "11.","10.","172."};
char myIp[64];
memset(myIp, 0, sizeof(myIp));
get_local_ip(myIp, prefixArr);
//the other server's ip for detecting it's alive or dead
pingIp = argv[1];
printf("my ip:%s-----ping ip:%s\n", myIp, pingIp);
//socket()
sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
struct sockaddr_in r_addr;
r_addr.sin_family = AF_INET;
r_addr.sin_addr.s_addr = inet_addr(myIp);
r_addr.sin_port = 0;
bind(sockfd, (struct sockaddr *) &r_addr, sizeof(r_addr));
if(sockfd<0){
printf("\nSocket file descriptor not received!!\n");
return 0;
}else{
printf("\nSocket file descriptor %d received\n", sockfd);
}
//once error seen, it will stop the loop
signal(SIGINT, intHandler);//catching interrupt
//send pings continuously
send_ping(sockfd, pingIp);
return 0;
}
The problem is that the value of myReceiveBytes is alway 64, even though the destination server has already been shutdown.

Your code is not actually decoding the received packet. In all likelihood, what you are receiving is an ICMP Destination Unreachable packet either from your own host or from your gateway.
Something along these lines:
#include <netinet/ip.h> /* struct iphdr */
...
...
struct sockaddr_in peerAddr;
unsigned char buf[1024];
unsigned int len = sizeof(peerAddr);
int bytes_received = recvfrom(sockfd, buf, sizeof(buf), 0,
(struct sockaddr *) &peerAddr, &len);
if (bytes_received > 0) {
printf("ICMP packet received from %s\n", inet_ntoa(peerAddr.sin_addr));
struct icmphdr *icmp = (struct icmphdr *) (buf + sizeof(struct iphdr));
switch (icmp->type) {
case ICMP_ECHOREPLY: printf("Type: ICMP_ECHOREPLY\n"); break;
case ICMP_DEST_UNREACH: printf("Type: ICMP_DEST_UNREACH\n"); break;
case ICMP_SOURCE_QUENCH: printf("Type: ICMP_SOURCE_QUENCH\n"); break;
case ICMP_REDIRECT: printf("Type: ICMP_REDIRECT\n"); break;
case ICMP_ECHO: printf("Type: ICMP_ECHO\n"); break;
case ICMP_TIME_EXCEEDED: printf("Type: ICMP_TIME_EXCEEDED\n"); break;
case ICMP_PARAMETERPROB: printf("Type: ICMP_PARAMETERPROB\n"); break;
case ICMP_TIMESTAMP: printf("Type: ICMP_TIMESTAMP\n"); break;
case ICMP_TIMESTAMPREPLY: printf("Type: ICMP_TIMESTAMPREPLY\n"); break;
case ICMP_INFO_REQUEST: printf("Type: ICMP_INFO_REQUEST\n"); break;
case ICMP_INFO_REPLY: printf("Type: ICMP_INFO_REPLY\n"); break;
case ICMP_ADDRESS: printf("Type: ICMP_ADDRESS\n"); break;
case ICMP_ADDRESSREPLY: printf("Type: ICMP_ADDRESSREPLY\n"); break;
default: printf("Type: <0x%02x>\n", icmp->type); break;
}
}

Related

CUB sum reduction with 2D pitched arrays

I am trying to perform a sum reduction using CUB and 2D arrays of type float/double.
Although it works for certain combinations of rows+columns, for relatively larger arrays, I get an illegal memory access error during the last transfer.
A minimal example is the following:
#include <stdio.h>
#include <stdlib.h>
#include <cub/device/device_reduce.cuh>
#include "cuda_runtime.h"
#ifdef DP
#define real double
#else
#define real float
#endif
void generatedata(const int num, real* vec, real start, real finish) {
real rrange = finish - start;
for (auto i = 0; i < num; ++i)
vec[i] = rand() / float(RAND_MAX) * rrange + start;
}
real reduce_to_sum(const int num, const real* vec) {
real total = real(0.0);
for (auto i = 0; i < num; ++i)
total += vec[i];
return total;
}
int main() {
int rows = 2001;
int cols = 3145;
size_t msize = rows * cols;
real* data = (real*)malloc(msize * sizeof(real));
if (!data)
return -999;
generatedata(msize, data, 0., 50.);
real ref_sum = reduce_to_sum(msize, data);
real* d_data_in = nullptr;
real* d_data_out = nullptr;
size_t pitch_in, pitch_out;
cudaError_t err = cudaMallocPitch(&d_data_in, &pitch_in, cols * sizeof(real), rows);
if (err != cudaSuccess) {
printf("data_in :: %s \n", cudaGetErrorString(err));
return -999;
}
err = cudaMallocPitch(&d_data_out, &pitch_out, cols * sizeof(real), rows);
if (err != cudaSuccess) {
printf("data_out :: %s \n", cudaGetErrorString(err));
return -999;
}
err = cudaMemset(d_data_in, 0, rows * pitch_in);
if (err != cudaSuccess) {
printf("set data_in :: %s \n", cudaGetErrorString(err));
return -999;
}
err = cudaMemcpy2D(d_data_in, pitch_in, data, cols * sizeof(real), cols * sizeof(real), rows, cudaMemcpyHostToDevice);
if (err != cudaSuccess) {
printf("copy data :: %s \n", cudaGetErrorString(err));
return -999;
}
void* d_temp = nullptr;
size_t temp_bytes = 0;
cub::DeviceReduce::Sum(d_temp, temp_bytes, d_data_in, d_data_out, rows * pitch_out);
err = cudaMalloc(&d_temp, temp_bytes);
if (err != cudaSuccess) {
printf("temp :: %s \n", cudaGetErrorString(err));
return -999;
}
err = cudaMemset(d_data_out, 0, rows * pitch_out);
if (err != cudaSuccess) {
printf("set temp :: %s \n", cudaGetErrorString(err));
return -999;
}
// Run sum-reduction
cub::DeviceReduce::Sum(d_temp, temp_bytes, d_data_in, d_data_out, rows * pitch_out);
err = cudaGetLastError();
if (err != cudaSuccess) {
printf("reduction :: %s \n", cudaGetErrorString(err));
return -999;
}
real gpu_sum = real(0.0);
err = cudaMemcpy(&gpu_sum, d_data_out, sizeof(real), cudaMemcpyDeviceToHost);
if (err != cudaSuccess) {
printf("copy final :: %s \n", cudaGetErrorString(err));
return -999;
}
printf("Difference in sum (h)%f - (d)%f = %f \n", ref_sum, gpu_sum, ref_sum - gpu_sum);
if (data) free(data);
if (d_data_in) cudaFree(d_data_in);
if (d_data_out) cudaFree(d_data_out);
if (d_temp) cudaFree(d_temp);
cudaDeviceReset();
return 0;
}
The error is thrown at "copy final ::". I am bit confused as to why certain rows x columns work and others don't. I did notice it's the larger values that cause it, but can't get my head around.
Any suggestions would be much appreciated.
The 5th parameter of cub::DeviceReduce::Sum should be the number of input elements. However, rows * pitch_out is the size of the output buffer in bytes.
Assuming pitch_in % sizeof(real) == 0, the following call may work.
cub::DeviceReduce::Sum(d_temp, temp_bytes, d_data_in, d_data_out, rows * (pitch_in / sizeof(real)));
Also note that cub::DeviceReduce::Sum may return before the reduction is complete. In this case, if any error happened during execution, this error will be reported by cudaMemcpy.

Dissecting a complex type in C++ using the clang/llvm AST api

Let's say I have a program with the following declaration:
std::vector<std::vector<std::vector<std::string> *> > s;
Now I would like to tokenize this, cut it in parts:
std vector
std vector
std vector pointer
std string
When going through the source-code, this example will give me a VarDecl. If I understood it correctly, this VarDecl contains the whole declaration. Now I think the next step is invoking getType() on that VarDecl. But then what? I expected a method that would return e.g. an iterator or so.
Below you'll see what I have. This works fine for e.g. "int i" or "const char *const i = NULL;" even for "const std::string l = "12";" but "std::vector *> > s;" results in an "int"?(!?).
void dissectType(ASTContext *const Context, const QualType x)
{
if (x.isNull())
return;
QualType type = x.getNonReferenceType();
for(;!type.isNull();) {
if (type.hasQualifiers()) {
Qualifiers q = type.getQualifiers();
if (q.hasConst())
printf("const ");
if (q.hasVolatile())
printf("volatile ");
if (q.hasRestrict())
printf("restrict ");
}
const Type *t = type.getTypePtr();
if (!t) {
printf("null?\n");
break;
}
else if (t -> isPointerType())
printf("* ");
else if (t -> isFundamentalType()) {
std::string curType = type.getUnqualifiedType().getAsString();
printf("%s\n", curType.c_str());
break; // should be last entry in this chain
}
type = type->getPointeeType();
}
}

A more efficient way to Retrieve records into a JSON array in MySQL? C

I am using MySQL in my C application. I have created a function
GetInDB(char *query, cJSON **json){...
that will allocate the json as a json array, query the db, and store the records in the array. The problem is that it seems difficult to quickly get the field name of each column in a table. Since I don't know the string length of each name in advance, I have to iterate through the results and dynamically allocate (!) a string that is large enough to hold each one. Then, I have to iterate through each record. Is there a better way?
int GetInDB(const char *query, cJSON **json)
{
if(*json != NULL){
cJSON_Delete(*json);
}
*json = cJSON_CreateArray();
if (mysql_query(mysqldb, query))
{
fprintf(stderr, "%s\n", mysql_error(mysqldb));
return -1;
}
MYSQL_RES *result = mysql_store_result(mysqldb);
if (result == NULL)
{
fprintf(stderr, "%s\n", mysql_error(mysqldb));
return -1;
}
int num_fields = mysql_num_fields(result);
int i;
MYSQL_ROW row;
MYSQL_FIELD *field;
char *Columns[num_fields];
int which = 0;
while((field = mysql_fetch_field(result)))
{
Columns[which] = (char*)malloc(strlen(field->name)+1);
strcpy(Columns[which], field->name);
which++;
}
while ((row = mysql_fetch_row(result)))
{
cJSON *obj = cJSON_CreateObject();
for(i = 0; i < num_fields; i++)
{
cJSON_AddStringToObject(obj, Columns[i], row[i] ? row[i] : "NULL");
}
cJSON_AddItemToArray(*json,obj);
}
mysql_free_result(result);
for(i=0; i<num_fields; i++){
free(Columns[i]);
}
return 0;
}

How to download a file from http using C?

I spent the last days trying to figure out how to download a file from an URL.
This is my first challenge with socket and I'm using it to have an understanding of protocols so I would like to do it without cURL libraries and only in C language!!
I searched a lot....now I'm able to printf the source code of a page but I think it's different with a file, I don't have only to put the received data from a buffer to a file, right?
any tips?
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
int main(void)
{
char domain[] = "www.sstatic.net", path[]="stackexchange/img/logos/so/so-logo-med.png"; //example
int sock, bytes_received;
char send_data[1024],recv_data[9999], *p;
struct sockaddr_in server_addr;
struct hostent *he;
FILE *fp;
he = gethostbyname(domain);
if (he == NULL){
herror("gethostbyname");
exit(1);
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0))== -1){
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1){
perror("Connect");
exit(1);
}
snprintf(send_data, sizeof(send_data), "GET /%s HTTP/1.1\r\nHost: /%s\r\n\r\n", path, domain);
//printf("%s\n", send_data);
send(sock, send_data, strlen(send_data), 0);
printf("Data sended.\n");
fp=fopen("received_file","wb");
bytes_received = recv(sock, recv_data, 9999, 0);
recv_data[bytes_received] = '\0';
printf("Data receieved.\n");
printf("%s\n", recv_data);
p = strstr(recv_data, "\r\n\r\n"); //to find "\r\n\r\n" sequence and put the pointer p after that
p=p+4;
fwrite(p,strlen(p),1,fp);
close(sock);
fclose(fp);
return 0;
}
UPDATE 1 thanks to milevyo for some improvements!
It works good with a txt file but it doesn't with other kinds of file (png in this case)
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
int main(void){
//char domain[] = "www.gnu.org", path[]="/licenses/gpl.txt"; //example
char domain[] = "sstatic.net", path[]="stackexchange/img/logos/so/so-logo-med.png"; //example
int sock, bytes_received;
char send_data[1024],recv_data[9999];
struct sockaddr_in server_addr;
struct hostent *he;
FILE *fp;
he = gethostbyname(domain);
if (he == NULL){
herror("gethostbyname");
exit(1);
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0))== -1){
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(server_addr.sin_zero),8);
printf("Connecting ...\n");
if (connect(sock, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1){
perror("Connect");
exit(1);
}
printf("Sending data ...\n");
snprintf(send_data, sizeof(send_data), "GET /%s HTTP/1.1\r\nHost: /%s\r\n\r\n", path, domain);
if(send(sock, send_data, strlen(send_data), 0)==-1){
perror("send");
exit(2);
}
printf("Data sent.\n");
fp=fopen("received_file","wb");
printf("Recieving data...\n\n");
while((bytes_received = recv(sock, recv_data, 9999, 0))>0){
if(bytes_received==-1){
perror("recieve");
exit(3);
}
recv_data[bytes_received] = '\0';
fwrite(recv_data,bytes_received,1,fp);
printf("%s", recv_data);
}
close(sock);
fclose(fp);
printf("\n\nDone.\n\n");
return 0;
}
this code produce a 334 bytes file (instead of 12,4kb of the original file) with this inside:
HTTP/1.1 400 Bad Request
Date: Sat, 28 Nov 2015 16:20:45 GMT
Content-Type: text/html
Content-Length: 177
Connection: close
Server: -nginx
CF-RAY: -
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>cloudflare-nginx</center>
</body>
</html>
somebody knows how to fix this "400 Bad Request"?
This is an update for the previous posted code. The http protocol is far to be implementation in just a small example.
reformatting the code , or giving a modification to it is more than welcome.
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <string.h>
int ReadHttpStatus(int sock){
char c;
char buff[1024]="",*ptr=buff+1;
int bytes_received, status;
printf("Begin Response ..\n");
while(bytes_received = recv(sock, ptr, 1, 0)){
if(bytes_received==-1){
perror("ReadHttpStatus");
exit(1);
}
if((ptr[-1]=='\r') && (*ptr=='\n' )) break;
ptr++;
}
*ptr=0;
ptr=buff+1;
sscanf(ptr,"%*s %d ", &status);
printf("%s\n",ptr);
printf("status=%d\n",status);
printf("End Response ..\n");
return (bytes_received>0)?status:0;
}
//the only filed that it parsed is 'Content-Length'
int ParseHeader(int sock){
char c;
char buff[1024]="",*ptr=buff+4;
int bytes_received, status;
printf("Begin HEADER ..\n");
while(bytes_received = recv(sock, ptr, 1, 0)){
if(bytes_received==-1){
perror("Parse Header");
exit(1);
}
if(
(ptr[-3]=='\r') && (ptr[-2]=='\n' ) &&
(ptr[-1]=='\r') && (*ptr=='\n' )
) break;
ptr++;
}
*ptr=0;
ptr=buff+4;
//printf("%s",ptr);
if(bytes_received){
ptr=strstr(ptr,"Content-Length:");
if(ptr){
sscanf(ptr,"%*s %d",&bytes_received);
}else
bytes_received=-1; //unknown size
printf("Content-Length: %d\n",bytes_received);
}
printf("End HEADER ..\n");
return bytes_received ;
}
int main(void){
char domain[] = "sstatic.net", path[]="stackexchange/img/logos/so/so-logo-med.png";
int sock, bytes_received;
char send_data[1024],recv_data[1024], *p;
struct sockaddr_in server_addr;
struct hostent *he;
he = gethostbyname(domain);
if (he == NULL){
herror("gethostbyname");
exit(1);
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0))== -1){
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(server_addr.sin_zero),8);
printf("Connecting ...\n");
if (connect(sock, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1){
perror("Connect");
exit(1);
}
printf("Sending data ...\n");
snprintf(send_data, sizeof(send_data), "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", path, domain);
if(send(sock, send_data, strlen(send_data), 0)==-1){
perror("send");
exit(2);
}
printf("Data sent.\n");
//fp=fopen("received_file","wb");
printf("Recieving data...\n\n");
int contentlengh;
if(ReadHttpStatus(sock) && (contentlengh=ParseHeader(sock))){
int bytes=0;
FILE* fd=fopen("test.png","wb");
printf("Saving data...\n\n");
while(bytes_received = recv(sock, recv_data, 1024, 0)){
if(bytes_received==-1){
perror("recieve");
exit(3);
}
fwrite(recv_data,1,bytes_received,fd);
bytes+=bytes_received;
printf("Bytes recieved: %d from %d\n",bytes,contentlengh);
if(bytes==contentlengh)
break;
}
fclose(fd);
}
close(sock);
printf("\n\nDone.\n\n");
return 0;
}
Try some thing like below: -
#include <sys/socket.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define BUFLEN 4096
#define HOST "www.t.edu.pk"
#define PORT 443
int main()
{
int sock, iResult;
char *cmd, *ip;
char recvbuf[BUFLEN];
//
struct sockaddr_in sin;
struct hostent* hent;
//
hent = gethostbyname(HOST);
if(hent == NULL)
{
printf("gethostbyname failed: %d\n", errno);
return -1;
}
printf("gethostbyname succeeded\n");
ip = inet_ntoa(*((struct in_addr*)hent->h_addr_list[0]));
printf("Host IP: %s\n", ip);
//
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1)
{
printf("socket failed: %d\n", errno);
return -1;
}
printf("socket created\n");
//
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(ip);
sin.sin_port = htons(PORT);
iResult = connect(sock, (struct sockaddr*)&sin, sizeof(sin));
if(iResult < 0)
{
printf("connect failed: %d\n", errno);
return -1;
}
printf("connect succeeded\n");
//
iResult = SSL_library_init();
if(iResult < 0)
{
printf("SSL failed\n");
return -1;
}
printf("SSL library initialised\n");
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
SSL_load_error_strings();
SSL_CTX* ctx = SSL_CTX_new(TLSv1_2_client_method());
if(ctx == NULL)
{
printf("ctx failed\n");
ERR_print_errors_fp(stderr);
return -1;
}
printf("ctx loaded\n");
SSL* ssl = SSL_new(ctx);
if(ssl == NULL)
{
printf("ssl failed\n");
ERR_print_errors_fp(stderr);
return -1;
}
printf("ssl loaded\n");
SSL_set_fd(ssl, sock);
SSL_connect(ssl);
//
cmd = "GET / HTTP/1.1\r\nHost: www.t.edu.pk\r\n\r\n";
iResult = SSL_write(ssl, cmd, strlen(cmd));
if(iResult <= 0)
{
printf("SSL write failed\n");
ERR_print_errors_fp(stderr);
return -1;
}
printf("Byte(s) sent: %d\n", iResult);
bzero(recvbuf, BUFLEN);
do
{
iResult = SSL_read(ssl, recvbuf, BUFLEN - 1);
if(iResult < 0)
{
printf("error receiving data\n");
break;
}
if(iResult == 0)
{
printf("host closed connection\n");
break;
}
printf("%s\n", recvbuf);
}while(iResult > 0);
//
iResult = SSL_shutdown(ssl);
if(iResult == 0)
{
printf("SSL shutdown in progress...\n");
}
iResult = SSL_shutdown(ssl);
if(iResult == 1)
{
printf("SSL shutdown complete!\n");
}
if(iResult == -1)
{
printf("SSL shutdown unsuccessful!\n");
}
SSL_CTX_free(ctx);
//
iResult = shutdown(sock, SHUT_RDWR);
if(iResult == -1)
{
printf("Socket shutdown failed: %d\n", errno);
return -1;
}
printf("Socket shutdown succeeded\n");
iResult = close(sock);
if(iResult != 0)
{
printf("error closing socket: %d\n", errno);
return -1;
}
printf("Socket closed\n");
//
return 0;
}
This work for C/C++ in linux Environment. You can run it by makefile, or just add -lcurl option in g++.
Notice that should have lib cURL.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
FILE *fp = fopen("file.txt", "w");
char outfilename[FILENAME_MAX] = "file_downloaded.txt";
FILE *fp1 = fopen(outfilename,"wb");
struct MemoryStruct {
char *memory;
size_t size;
};
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
char *ptr = (char*)realloc(mem->memory, mem->size + realsize + 1);
if(!ptr) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
fprintf(fp, "%ld - %ld - %ld\n", realsize, size, nmemb);
size_t written = fwrite(contents, size, nmemb, fp1);
mem->memory = ptr;
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
int main(void)
{
char link_download[] = "https://www.example.com/";
CURL *curl_handle;
CURLcode res;
struct MemoryStruct chunk;
chunk.memory = (char*)malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
curl_global_init(CURL_GLOBAL_ALL);
/* init the curl session */
curl_handle = curl_easy_init();
/* specify URL to get */
curl_easy_setopt(curl_handle, CURLOPT_URL, link_download);
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
/* some servers do not like requests that are made without a user-agent
field, so we provide one */
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
/* get it! */
res = curl_easy_perform(curl_handle);
/* check for errors */
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else {
/*
* Now, our chunk.memory points to a memory block that is chunk.size
* bytes big and contains the remote file.
*
* Do something nice with it!
*/
printf("%lu bytes retrieved\n", (unsigned long)chunk.size);
}
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
free(chunk.memory);
/* we are done with libcurl, so clean it up */
curl_global_cleanup();
fclose(fp);
fclose(fp1);
return 0;
}

CUDA NPP image dot product having cudaErrorUnknown

The function nppiDotProd_8u64f_C1R causes a cudaErrorUnknown. I'm able to compile and run properly boxFilterNPP and histEqualizationNPP so I assume my system is healthy. I'm running with a GTX470 (compute capability 2.0), CUDA 5.5 and VS2012 x64 on Windows7. I've also run many variations of it on two systems and having the same problem. Here is the code:
NppGpuComputeCapability capability = nppGetGpuComputeCapability();
NppiSize sizeROI;
sizeROI.width = 640;
sizeROI.height = 480;
int nBufferSize = 0;
NppStatus status = nppiDotProdGetBufferHostSize_8u64f_C1R(sizeROI,&nBufferSize);
if(status != NPP_SUCCESS) return status;
unsigned char *pDeviceBuffer;
cudaError_t err = cudaMalloc((void**)&pDeviceBuffer,nBufferSize);
if(err != cudaSuccess) return err;
int stepByte1 = 0;
Npp8u * buf1 = nppiMalloc_8u_C1(sizeROI.width, sizeROI.height, &stepByte1);
status = nppiSet_8u_C1R(1,buf1,stepByte1,sizeROI);
if(status != NPP_SUCCESS) return status;
int stepByte2 = 0;
Npp8u * buf2 = nppiMalloc_8u_C1(sizeROI.width, sizeROI.height, &stepByte2);
status = nppiSet_8u_C1R(1,buf2,stepByte2,sizeROI);
if(status != NPP_SUCCESS) return status;
err = cudaDeviceSynchronize();
if(err != cudaSuccess) return err;
double dp = 0;
status = nppiDotProd_8u64f_C1R(buf1,stepByte1,buf2,stepByte2,sizeROI,&dp,pDeviceBuffer);
if(status != NPP_SUCCESS) return status;
err = cudaDeviceSynchronize(); // return cudaErrorUnknown
// CUDA memchecker gives me "OutOfRangeStore" exception
if(err != cudaSuccess) return err;
printf("result: %f\n", dp);
nppiFree(buf1);
nppiFree(buf2);
cudaFree(pDeviceBuffer);
Any idea about my problem?
Thank you very much!!
The result argument in that nppiDotProd call must be a device pointer, not a host pointer. You can fix it by allocating memory for dp on the device, something like :
double * dp ;
cudaMalloc((void **)(&dp), sizeof(Npp64f) * 1);
status = nppiDotProd_8u64f_C1R(buf1,stepByte1,buf2,stepByte2,sizeROI,dp,pDeviceBuffer);
if(status != NPP_SUCCESS) return status;
[disclaimer: written in browser, not compiled or tested, use a own risk]
You will obviously need to copy the result of the dot product back to the host if you need it.