Statistics
| Branch: | Revision:

grapes / src / net_helper.c @ d7aae2f0

History | View | Annotate | Download (4.99 KB)

1 8ab58ec7 Luca Abeni
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *  Copyright (c) 2010 Csaba Kiraly
4
 *
5
 *  This is free software; see lgpl-2.1.txt
6
 */
7
8 480921a6 Luca Abeni
#include <sys/types.h>
9
#include <sys/socket.h>
10
#include <netinet/in.h>
11
#include <arpa/inet.h>
12
#include <unistd.h>
13
#include <stdlib.h>
14
#include <stdio.h>
15
#include <string.h>
16
17 155319cd Luca Abeni
#include "net_helper.h"
18 480921a6 Luca Abeni
19 651ed37d Luca
struct nodeID {
20 480921a6 Luca Abeni
  struct sockaddr_in addr;
21 651ed37d Luca
  int fd;
22 480921a6 Luca Abeni
};
23
24 0cb8677a Luca Abeni
int wait4data(const struct nodeID *s, struct timeval *tout, int *user_fds)
25 b576198c Luca Abeni
{
26
  fd_set fds;
27 0cb8677a Luca Abeni
  int i, res, max_fd;
28 b576198c Luca Abeni
29
  FD_ZERO(&fds);
30 d7aae2f0 Luca Abeni
  if (s) {
31
    max_fd = s->fd;
32
    FD_SET(s->fd, &fds);
33
  } else {
34
    max_fd = -1;
35
  }
36 0cb8677a Luca Abeni
  if (user_fds) {
37
    for (i = 0; user_fds[i] != -1; i++) {
38
      FD_SET(user_fds[i], &fds);
39
      if (user_fds[i] > max_fd) {
40
        max_fd = user_fds[i];
41
      }
42
    }
43 92bdbfcd Luca Abeni
  }
44 0cb8677a Luca Abeni
  res = select(max_fd + 1, &fds, NULL, NULL, tout);
45 92bdbfcd Luca Abeni
  if (res <= 0) {
46
    return res;
47
  }
48 d7aae2f0 Luca Abeni
  if (s && FD_ISSET(s->fd, &fds)) {
49 b576198c Luca Abeni
    return 1;
50
  }
51
52 0cb8677a Luca Abeni
  /* If execution arrives here, user_fds cannot be 0
53
     (an FD is ready, and it's not s->fd) */
54
  for (i = 0; user_fds[i] != -1; i++) {
55
    if (!FD_ISSET(user_fds[i], &fds)) {
56
      user_fds[i] = -2;
57
    }
58
  }
59
60 92bdbfcd Luca Abeni
  return 2;
61 b576198c Luca Abeni
}
62
63
struct nodeID *create_node(const char *IPaddr, int port)
64 480921a6 Luca Abeni
{
65 651ed37d Luca
  struct nodeID *s;
66 480921a6 Luca Abeni
  int res;
67
68 651ed37d Luca
  s = malloc(sizeof(struct nodeID));
69
  memset(s, 0, sizeof(struct nodeID));
70 480921a6 Luca Abeni
  s->addr.sin_family = AF_INET;
71
  s->addr.sin_port = htons(port);
72
  res = inet_aton(IPaddr, &s->addr.sin_addr);
73
  if (res == 0) {
74
    free(s);
75
76 3bcb55e5 Luca
    return NULL;
77 480921a6 Luca Abeni
  }
78
79 b7790a94 Luca Abeni
  s->fd = -1;
80 b576198c Luca Abeni
81
  return s;
82
}
83
84 c919f1bf Csaba Kiraly
struct nodeID *net_helper_init(const char *my_addr, int port, const char *config)
85 b576198c Luca Abeni
{
86
  int res;
87
  struct nodeID *myself;
88
89
  myself = create_node(my_addr, port);
90
  if (myself == NULL) {
91
    fprintf(stderr, "Error creating my socket (%s:%d)!\n", my_addr, port);
92
  }
93 b7790a94 Luca Abeni
  myself->fd =  socket(AF_INET, SOCK_DGRAM, 0);
94
  if (myself->fd < 0) {
95
    free(myself);
96
    
97
    return NULL;
98
  }
99 b576198c Luca Abeni
  fprintf(stderr, "My sock: %d\n", myself->fd);
100
101
  res = bind(myself->fd, (struct sockaddr *)&myself->addr, sizeof(struct sockaddr_in));
102 651ed37d Luca
  if (res < 0) {
103
    /* bind failed: not a local address... Just close the socket! */
104 b576198c Luca Abeni
    close(myself->fd);
105
    free(myself);
106
107
    return NULL;
108 480921a6 Luca Abeni
  }
109
110 b576198c Luca Abeni
  return myself;
111 480921a6 Luca Abeni
}
112
113 458b1d7e Luca Abeni
void bind_msg_type (uint8_t msgtype)
114
{
115
}
116
117 5ada309a Luca Abeni
int send_to_peer(const struct nodeID *from, struct nodeID *to, const uint8_t *buffer_ptr, int buffer_size)
118 651ed37d Luca
{
119 41f12636 Luca Abeni
  static struct msghdr msg;
120
  static uint8_t my_hdr;
121
  struct iovec iov[2];
122
  int res;
123
124
  iov[0].iov_base = &my_hdr;
125
  iov[0].iov_len = 1;
126
  msg.msg_name = &to->addr;
127
  msg.msg_namelen = sizeof(struct sockaddr_in);
128
  msg.msg_iovlen = 2;
129
  msg.msg_iov = iov;
130
  
131
  do {
132
    iov[1].iov_base = buffer_ptr;
133
    if (buffer_size > 1024 * 60) {
134
      iov[1].iov_len = 1024 * 60;
135
      my_hdr = 0;
136
    } else {
137
      iov[1].iov_len = buffer_size;
138
      my_hdr = 1;
139
    }
140
    buffer_size -= iov[1].iov_len;
141
    buffer_ptr += iov[1].iov_len;
142
    res = sendmsg(from->fd, &msg, 0);
143
  } while (buffer_size > 0);
144
145
  return res;
146 480921a6 Luca Abeni
}
147
148 b576198c Luca Abeni
int recv_from_peer(const struct nodeID *local, struct nodeID **remote, uint8_t *buffer_ptr, int buffer_size)
149 480921a6 Luca Abeni
{
150 41f12636 Luca Abeni
  int res, recv;
151 480921a6 Luca Abeni
  struct sockaddr_in raddr;
152 41f12636 Luca Abeni
  static struct msghdr msg;
153
  static uint8_t my_hdr;
154
  struct iovec iov[2];
155
156
  iov[0].iov_base = &my_hdr;
157
  iov[0].iov_len = 1;
158
  msg.msg_name = &raddr;
159
  msg.msg_namelen = sizeof(struct sockaddr_in);
160
  msg.msg_iovlen = 2;
161
  msg.msg_iov = iov;
162 480921a6 Luca Abeni
163 651ed37d Luca
  *remote = malloc(sizeof(struct nodeID));
164
  if (*remote == NULL) {
165
    return -1;
166
  }
167 41f12636 Luca Abeni
168
  recv = 0;
169
  do {
170
    iov[1].iov_base = buffer_ptr;
171
    if (buffer_size > 1024 * 60) {
172
      iov[1].iov_len = 1024 * 60;
173
    } else {
174
      iov[1].iov_len = buffer_size;
175
    }
176
    buffer_size -= iov[1].iov_len;
177
    buffer_ptr += iov[1].iov_len;
178
    res = recvmsg(local->fd, &msg, 0);
179
    recv += (res - 1);
180
  } while ((my_hdr == 0) && (buffer_size > 0));
181
  memcpy(&(*remote)->addr, &raddr, msg.msg_namelen);
182 651ed37d Luca
  (*remote)->fd = -1;
183 4dbe13f0 Luca
184 41f12636 Luca Abeni
  return recv;
185 480921a6 Luca Abeni
}
186
187 651ed37d Luca
const char *node_addr(const struct nodeID *s)
188 480921a6 Luca Abeni
{
189
  static char addr[256];
190
191
  sprintf(addr, "%s:%d", inet_ntoa(s->addr.sin_addr), ntohs(s->addr.sin_port));
192
193
  return addr;
194
}
195
196 5ada309a Luca Abeni
struct nodeID *nodeid_dup(struct nodeID *s)
197 480921a6 Luca Abeni
{
198 651ed37d Luca
  struct nodeID *res;
199 480921a6 Luca Abeni
200 651ed37d Luca
  res = malloc(sizeof(struct nodeID));
201 480921a6 Luca Abeni
  if (res != NULL) {
202 651ed37d Luca
    memcpy(res, s, sizeof(struct nodeID));
203 480921a6 Luca Abeni
  }
204
205
  return res;
206
}
207 2edb3e55 Luca Abeni
208 651ed37d Luca
int nodeid_equal(const struct nodeID *s1, const struct nodeID *s2)
209 480921a6 Luca Abeni
{
210 5891be7d Luca
  return (memcmp(&s1->addr, &s2->addr, sizeof(struct sockaddr_in)) == 0);
211 480921a6 Luca Abeni
}
212
213 20903c9c Csaba Kiraly
int nodeid_dump(uint8_t *b, const struct nodeID *s, size_t max_write_size)
214 480921a6 Luca Abeni
{
215 20903c9c Csaba Kiraly
  if (max_write_size < sizeof(struct sockaddr_in)) return -1;
216
217 4abf6307 Csaba Kiraly
  memcpy(b, &s->addr, sizeof(struct sockaddr_in));
218 480921a6 Luca Abeni
219 4abf6307 Csaba Kiraly
  return sizeof(struct sockaddr_in);
220 480921a6 Luca Abeni
}
221
222 651ed37d Luca
struct nodeID *nodeid_undump(const uint8_t *b, int *len)
223 480921a6 Luca Abeni
{
224 651ed37d Luca
  struct nodeID *res;
225
  res = malloc(sizeof(struct nodeID));
226 480921a6 Luca Abeni
  if (res != NULL) {
227 4abf6307 Csaba Kiraly
    memcpy(&res->addr, b, sizeof(struct sockaddr_in));
228 31806e09 Luca Abeni
    res->fd = -1;
229 480921a6 Luca Abeni
  }
230 4abf6307 Csaba Kiraly
  *len = sizeof(struct sockaddr_in);
231 480921a6 Luca Abeni
232
  return res;
233
}
234 678c612d Luca Abeni
235
void nodeid_free(struct nodeID *s)
236
{
237
  free(s);
238
}
239
240 e55fe1f8 Marco Biazzini
const char *node_ip(const struct nodeID *s)
241
{
242 2edb3e55 Luca Abeni
  static char ip[64];
243 e55fe1f8 Marco Biazzini
244 2edb3e55 Luca Abeni
  sprintf(ip, "%s", inet_ntoa(s->addr.sin_addr));
245 e55fe1f8 Marco Biazzini
246 2edb3e55 Luca Abeni
  return ip;
247 e55fe1f8 Marco Biazzini
}