blob: ea44d863019fe766f745996dab3fc6c8dbeaf9de [file] [log] [blame]
Jeff Thompson7850d782013-07-14 17:59:14 -07001/**
2 * @author: Jeff Thompson
3 * See COPYING for copyright and distribution information.
4 */
5
6#include "TcpTransport.h"
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h>
Jeff Thompson7850d782013-07-14 17:59:14 -070011#include <netdb.h>
12#include <sys/types.h>
13#include <netinet/in.h>
14#include <sys/socket.h>
Jeff Thompson7850d782013-07-14 17:59:14 -070015#include <arpa/inet.h>
Jeff Thompson6c12a432013-07-15 12:09:12 -070016#include "../util/ndn_memory.h"
Jeff Thompson7850d782013-07-14 17:59:14 -070017
Jeff Thompson0d567da2013-07-14 22:10:21 -070018ndn_Error ndn_TcpTransport_connect(struct ndn_TcpTransport *self, char *host, unsigned short port)
Jeff Thompson7850d782013-07-14 17:59:14 -070019{
Jeff Thompson0d567da2013-07-14 22:10:21 -070020 if (self->socketDescriptor >= 0) {
21 close(self->socketDescriptor);
22 self->socketDescriptor = -1;
23 }
Jeff Thompson7850d782013-07-14 17:59:14 -070024
Jeff Thompson0d567da2013-07-14 22:10:21 -070025 struct addrinfo hints;
Jeff Thompson6c12a432013-07-15 12:09:12 -070026 ndn_memset((unsigned char *)&hints, 0, sizeof(hints));
Jeff Thompson7850d782013-07-14 17:59:14 -070027 hints.ai_family = AF_UNSPEC;
28 hints.ai_socktype = SOCK_STREAM;
29
Jeff Thompson0d567da2013-07-14 22:10:21 -070030 char portString[10];
31 sprintf(portString, "%d", port);
32
33 struct addrinfo *serverInfo;
34 if (getaddrinfo(host, portString, &hints, &serverInfo) != 0)
35 return NDN_ERROR_TcpTransport_error_in_getaddrinfo;
Jeff Thompson7850d782013-07-14 17:59:14 -070036
37 // loop through all the results and connect to the first we can
38 struct addrinfo *p;
Jeff Thompson0d567da2013-07-14 22:10:21 -070039 int socketDescriptor;
Jeff Thompson7850d782013-07-14 17:59:14 -070040 for(p = serverInfo; p != NULL; p = p->ai_next) {
41 if ((socketDescriptor = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
42 continue;
43
44 if (connect(socketDescriptor, p->ai_addr, p->ai_addrlen) == -1) {
45 close(socketDescriptor);
46 continue;
47 }
48
49 break;
50 }
51
Jeff Thompson0d567da2013-07-14 22:10:21 -070052 if (p == NULL) {
53 freeaddrinfo(serverInfo);
54 return NDN_ERROR_TcpTransport_cannot_connect_to_socket;
55 }
Jeff Thompson7850d782013-07-14 17:59:14 -070056
Jeff Thompson0d567da2013-07-14 22:10:21 -070057 freeaddrinfo(serverInfo);
58 self->socketDescriptor = socketDescriptor;
Jeff Thompson7850d782013-07-14 17:59:14 -070059
Jeff Thompson0d567da2013-07-14 22:10:21 -070060 return 0;
61}
62
63ndn_Error ndn_TcpTransport_send(struct ndn_TcpTransport *self, unsigned char *data, unsigned int dataLength)
64{
65 if (self->socketDescriptor < 0)
66 return NDN_ERROR_TcpTransport_socket_is_not_open;
67
Jeff Thompson7850d782013-07-14 17:59:14 -070068 int nBytes;
69 while (1) {
Jeff Thompson0d567da2013-07-14 22:10:21 -070070 if ((nBytes = send(self->socketDescriptor, data, dataLength, 0)) < 0)
71 return NDN_ERROR_TcpTransport_error_in_send;
Jeff Thompson7850d782013-07-14 17:59:14 -070072 if (nBytes >= dataLength)
73 break;
74
Jeff Thompson0d567da2013-07-14 22:10:21 -070075 // Send more.
Jeff Thompson7850d782013-07-14 17:59:14 -070076 dataLength -= nBytes;
77 }
Jeff Thompson0d567da2013-07-14 22:10:21 -070078
79 return 0;
80}
81
82ndn_Error ndn_TcpTransport_receive
83(struct ndn_TcpTransport *self, unsigned char *buffer, unsigned int bufferLength, unsigned int *nBytesOut)
84{
85 if (self->socketDescriptor < 0)
86 return NDN_ERROR_TcpTransport_socket_is_not_open;
87
88 int nBytes;
89 if ((nBytes = recv(self->socketDescriptor, buffer, bufferLength, 0)) == -1)
90 return NDN_ERROR_TcpTransport_error_in_recv;
91
92 *nBytesOut = (unsigned int)nBytes;
Jeff Thompson7850d782013-07-14 17:59:14 -070093
Jeff Thompson0d567da2013-07-14 22:10:21 -070094 return 0;
Jeff Thompson7850d782013-07-14 17:59:14 -070095}