blob: a6fcbace39f15a57a6a2d39138b19c11626987df [file] [log] [blame]
Jeff Thompson7790c682013-07-17 17:22:12 -07001/**
2 * @author: Jeff Thompson
3 * See COPYING for copyright and distribution information.
4 */
5
Jeff Thompson53412192013-08-06 13:35:50 -07006#include "socket-transport.h"
Jeff Thompson7790c682013-07-17 17:22:12 -07007
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h>
11#include <netdb.h>
12#include <sys/types.h>
13#include <netinet/in.h>
14#include <sys/socket.h>
15#include <arpa/inet.h>
16#include "../util/ndn_memory.h"
17
Jeff Thompson0aa754a2013-07-17 17:42:28 -070018ndn_Error ndn_SocketTransport_connect(struct ndn_SocketTransport *self, ndn_SocketType socketType, char *host, unsigned short port)
Jeff Thompson7790c682013-07-17 17:22:12 -070019{
20 if (self->socketDescriptor >= 0) {
21 close(self->socketDescriptor);
22 self->socketDescriptor = -1;
23 }
24
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070025 struct addrinfo hints;
26 ndn_memset((unsigned char *)&hints, 0, sizeof(hints));
27 hints.ai_family = AF_UNSPEC;
Jeff Thompson0aa754a2013-07-17 17:42:28 -070028 if (socketType == SOCKET_TCP)
29 hints.ai_socktype = SOCK_STREAM;
30 else if (socketType == SOCKET_UDP)
31 hints.ai_socktype = SOCK_DGRAM;
32 else
33 return NDN_ERROR_unrecognized_ndn_SocketTransport;
Jeff Thompson7790c682013-07-17 17:22:12 -070034
35 char portString[10];
36 sprintf(portString, "%d", port);
37
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070038 struct addrinfo *serverInfo;
39 if (getaddrinfo(host, portString, &hints, &serverInfo) != 0)
40 return NDN_ERROR_SocketTransport_error_in_getaddrinfo;
Jeff Thompson7790c682013-07-17 17:22:12 -070041
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070042 // loop through all the results and connect to the first we can
43 struct addrinfo *p;
Jeff Thompson7790c682013-07-17 17:22:12 -070044 int socketDescriptor;
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070045 for(p = serverInfo; p != NULL; p = p->ai_next) {
46 if ((socketDescriptor = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
47 continue;
Jeff Thompson7790c682013-07-17 17:22:12 -070048
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070049 if (connect(socketDescriptor, p->ai_addr, p->ai_addrlen) == -1) {
50 close(socketDescriptor);
51 continue;
52 }
Jeff Thompson7790c682013-07-17 17:22:12 -070053
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070054 break;
Jeff Thompson7790c682013-07-17 17:22:12 -070055 }
56
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070057 if (p == NULL) {
58 freeaddrinfo(serverInfo);
59 return NDN_ERROR_SocketTransport_cannot_connect_to_socket;
60 }
61
62 freeaddrinfo(serverInfo);
Jeff Thompson7790c682013-07-17 17:22:12 -070063 self->socketDescriptor = socketDescriptor;
64
Jeff Thompsonadaf9232013-08-08 14:30:29 -070065 return NDN_ERROR_success;
Jeff Thompson7790c682013-07-17 17:22:12 -070066}
67
Jeff Thompson0aa754a2013-07-17 17:42:28 -070068ndn_Error ndn_SocketTransport_send(struct ndn_SocketTransport *self, unsigned char *data, unsigned int dataLength)
Jeff Thompson7790c682013-07-17 17:22:12 -070069{
70 if (self->socketDescriptor < 0)
Jeff Thompson0aa754a2013-07-17 17:42:28 -070071 return NDN_ERROR_SocketTransport_socket_is_not_open;
Jeff Thompson7790c682013-07-17 17:22:12 -070072
73 int nBytes;
74 while (1) {
75 if ((nBytes = send(self->socketDescriptor, data, dataLength, 0)) < 0)
Jeff Thompson0aa754a2013-07-17 17:42:28 -070076 return NDN_ERROR_SocketTransport_error_in_send;
Jeff Thompson7790c682013-07-17 17:22:12 -070077 if (nBytes >= dataLength)
78 break;
79
80 // Send more.
81 dataLength -= nBytes;
82 }
83
Jeff Thompsonadaf9232013-08-08 14:30:29 -070084 return NDN_ERROR_success;
Jeff Thompson7790c682013-07-17 17:22:12 -070085}
86
Jeff Thompson0aa754a2013-07-17 17:42:28 -070087ndn_Error ndn_SocketTransport_receive
88(struct ndn_SocketTransport *self, unsigned char *buffer, unsigned int bufferLength, unsigned int *nBytesOut)
Jeff Thompson7790c682013-07-17 17:22:12 -070089{
90 if (self->socketDescriptor < 0)
Jeff Thompson0aa754a2013-07-17 17:42:28 -070091 return NDN_ERROR_SocketTransport_socket_is_not_open;
Jeff Thompson7790c682013-07-17 17:22:12 -070092
93 int nBytes;
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070094 if ((nBytes = recv(self->socketDescriptor, buffer, bufferLength, 0)) == -1)
Jeff Thompson0aa754a2013-07-17 17:42:28 -070095 return NDN_ERROR_SocketTransport_error_in_recv;
Jeff Thompson7790c682013-07-17 17:22:12 -070096
97 *nBytesOut = (unsigned int)nBytes;
98
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070099 return NDN_ERROR_success;
Jeff Thompson7790c682013-07-17 17:22:12 -0700100}
Jeff Thompson57963882013-08-05 16:01:25 -0700101
102ndn_Error ndn_SocketTransport_close(struct ndn_SocketTransport *self)
103{
104 if (self->socketDescriptor < 0)
105 // Already closed. Do nothing.
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700106 return NDN_ERROR_success;
Jeff Thompson57963882013-08-05 16:01:25 -0700107
108 if (close(self->socketDescriptor) != 0)
109 return NDN_ERROR_SocketTransport_error_in_close;
110
111 self->socketDescriptor = -1;
112
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700113 return NDN_ERROR_success;
Jeff Thompson57963882013-08-05 16:01:25 -0700114}