Statistics
| Branch: | Revision:

grapes / src / net_helper.c @ 5232d493

History | View | Annotate | Download (5.25 KB)

1
/*
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
#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
#include "net_helper.h"
18

    
19
struct nodeID {
20
  struct sockaddr_in addr;
21
  int fd;
22
};
23

    
24
int wait4data(const struct nodeID *s, struct timeval *tout, int *user_fds)
25
{
26
  fd_set fds;
27
  int i, res, max_fd;
28

    
29
  FD_ZERO(&fds);
30
  if (s) {
31
    max_fd = s->fd;
32
    FD_SET(s->fd, &fds);
33
  } else {
34
    max_fd = -1;
35
  }
36
  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
  }
44
  res = select(max_fd + 1, &fds, NULL, NULL, tout);
45
  if (res <= 0) {
46
    return res;
47
  }
48
  if (s && FD_ISSET(s->fd, &fds)) {
49
    return 1;
50
  }
51

    
52
  /* 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
  return 2;
61
}
62

    
63
struct nodeID *create_node(const char *IPaddr, int port)
64
{
65
  struct nodeID *s;
66
  int res;
67

    
68
  s = malloc(sizeof(struct nodeID));
69
  memset(s, 0, sizeof(struct nodeID));
70
  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
    return NULL;
77
  }
78

    
79
  s->fd = -1;
80

    
81
  return s;
82
}
83

    
84
struct nodeID *net_helper_init(const char *my_addr, int port, const char *config)
85
{
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
  myself->fd =  socket(AF_INET, SOCK_DGRAM, 0);
94
  if (myself->fd < 0) {
95
    free(myself);
96
    
97
    return NULL;
98
  }
99
  fprintf(stderr, "My sock: %d\n", myself->fd);
100

    
101
  res = bind(myself->fd, (struct sockaddr *)&myself->addr, sizeof(struct sockaddr_in));
102
  if (res < 0) {
103
    /* bind failed: not a local address... Just close the socket! */
104
    close(myself->fd);
105
    free(myself);
106

    
107
    return NULL;
108
  }
109

    
110
  return myself;
111
}
112

    
113
void bind_msg_type (uint8_t msgtype)
114
{
115
}
116

    
117
void reg_message_send(int size, uint8_t type);
118

    
119
int send_to_peer(const struct nodeID *from, struct nodeID *to, const uint8_t *buffer_ptr, int buffer_size)
120
{
121
  static struct msghdr msg;
122
  static uint8_t my_hdr;
123
  struct iovec iov[2];
124
  int res;
125

    
126
  if (buffer_size <= 0) return;
127
  reg_message_send(buffer_size, buffer_ptr[0]);
128

    
129
  iov[0].iov_base = &my_hdr;
130
  iov[0].iov_len = 1;
131
  msg.msg_name = &to->addr;
132
  msg.msg_namelen = sizeof(struct sockaddr_in);
133
  msg.msg_iovlen = 2;
134
  msg.msg_iov = iov;
135
  
136
  do {
137
    iov[1].iov_base = buffer_ptr;
138
    if (buffer_size > 1024 * 60) {
139
      iov[1].iov_len = 1024 * 60;
140
      my_hdr = 0;
141
    } else {
142
      iov[1].iov_len = buffer_size;
143
      my_hdr = 1;
144
    }
145
    buffer_size -= iov[1].iov_len;
146
    buffer_ptr += iov[1].iov_len;
147
    res = sendmsg(from->fd, &msg, 0);
148
  } while (buffer_size > 0);
149

    
150
  return res;
151
}
152

    
153
void reg_message_recv(int size, uint8_t type);
154

    
155
int recv_from_peer(const struct nodeID *local, struct nodeID **remote, uint8_t *buffer_ptr, int buffer_size)
156
{
157
  int res, recv;
158
  struct sockaddr_in raddr;
159
  static struct msghdr msg;
160
  static uint8_t my_hdr;
161
  struct iovec iov[2];
162
  uint8_t *buffer_ptr_orig = buffer_ptr;
163

    
164
  iov[0].iov_base = &my_hdr;
165
  iov[0].iov_len = 1;
166
  msg.msg_name = &raddr;
167
  msg.msg_namelen = sizeof(struct sockaddr_in);
168
  msg.msg_iovlen = 2;
169
  msg.msg_iov = iov;
170

    
171
  *remote = malloc(sizeof(struct nodeID));
172
  if (*remote == NULL) {
173
    return -1;
174
  }
175

    
176
  recv = 0;
177
  do {
178
    iov[1].iov_base = buffer_ptr;
179
    if (buffer_size > 1024 * 60) {
180
      iov[1].iov_len = 1024 * 60;
181
    } else {
182
      iov[1].iov_len = buffer_size;
183
    }
184
    buffer_size -= iov[1].iov_len;
185
    buffer_ptr += iov[1].iov_len;
186
    res = recvmsg(local->fd, &msg, 0);
187
    recv += (res - 1);
188
  } while ((my_hdr == 0) && (buffer_size > 0));
189
  memcpy(&(*remote)->addr, &raddr, msg.msg_namelen);
190
  (*remote)->fd = -1;
191

    
192
  reg_message_recv(recv, buffer_ptr_orig[0]);
193

    
194
  return recv;
195
}
196

    
197
const char *node_addr(const struct nodeID *s)
198
{
199
  static char addr[256];
200

    
201
  sprintf(addr, "%s:%d", inet_ntoa(s->addr.sin_addr), ntohs(s->addr.sin_port));
202

    
203
  return addr;
204
}
205

    
206
struct nodeID *nodeid_dup(struct nodeID *s)
207
{
208
  struct nodeID *res;
209

    
210
  res = malloc(sizeof(struct nodeID));
211
  if (res != NULL) {
212
    memcpy(res, s, sizeof(struct nodeID));
213
  }
214

    
215
  return res;
216
}
217

    
218
int nodeid_equal(const struct nodeID *s1, const struct nodeID *s2)
219
{
220
  return (memcmp(&s1->addr, &s2->addr, sizeof(struct sockaddr_in)) == 0);
221
}
222

    
223
int nodeid_dump(uint8_t *b, const struct nodeID *s, size_t max_write_size)
224
{
225
  if (max_write_size < sizeof(struct sockaddr_in)) return -1;
226

    
227
  memcpy(b, &s->addr, sizeof(struct sockaddr_in));
228

    
229
  return sizeof(struct sockaddr_in);
230
}
231

    
232
struct nodeID *nodeid_undump(const uint8_t *b, int *len)
233
{
234
  struct nodeID *res;
235
  res = malloc(sizeof(struct nodeID));
236
  if (res != NULL) {
237
    memcpy(&res->addr, b, sizeof(struct sockaddr_in));
238
    res->fd = -1;
239
  }
240
  *len = sizeof(struct sockaddr_in);
241

    
242
  return res;
243
}
244

    
245
void nodeid_free(struct nodeID *s)
246
{
247
  free(s);
248
}
249

    
250
const char *node_ip(const struct nodeID *s)
251
{
252
  static char ip[64];
253

    
254
  sprintf(ip, "%s", inet_ntoa(s->addr.sin_addr));
255

    
256
  return ip;
257
}