Statistics
| Branch: | Revision:

grapes / som / net_helper.c @ 0cb8677a

History | View | Annotate | Download (4.74 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
  max_fd = s->fd;
31
  if (user_fds) {
32
    for (i = 0; user_fds[i] != -1; i++) {
33
      FD_SET(user_fds[i], &fds);
34
      if (user_fds[i] > max_fd) {
35
        max_fd = user_fds[i];
36
      }
37
    }
38
  }
39
  FD_SET(s->fd, &fds);
40
  res = select(max_fd + 1, &fds, NULL, NULL, tout);
41
  if (res <= 0) {
42
    return res;
43
  }
44
  if (FD_ISSET(s->fd, &fds)) {
45
    return 1;
46
  }
47

    
48
  /* If execution arrives here, user_fds cannot be 0
49
     (an FD is ready, and it's not s->fd) */
50
  for (i = 0; user_fds[i] != -1; i++) {
51
    if (!FD_ISSET(user_fds[i], &fds)) {
52
      user_fds[i] = -2;
53
    }
54
  }
55

    
56
  return 2;
57
}
58

    
59
struct nodeID *create_node(const char *IPaddr, int port)
60
{
61
  struct nodeID *s;
62
  int res;
63

    
64
  s = malloc(sizeof(struct nodeID));
65
  memset(s, 0, sizeof(struct nodeID));
66
  s->addr.sin_family = AF_INET;
67
  s->addr.sin_port = htons(port);
68
  res = inet_aton(IPaddr, &s->addr.sin_addr);
69
  if (res == 0) {
70
    free(s);
71

    
72
    return NULL;
73
  }
74

    
75
  s->fd = socket(AF_INET, SOCK_DGRAM, 0);
76
  if (s->fd < 0) {
77
    free(s);
78
    
79
    return NULL;
80
  }
81

    
82
  return s;
83
}
84

    
85
struct nodeID *net_helper_init(const char *my_addr, int port)
86
{
87
  int res;
88
  struct nodeID *myself;
89

    
90
  myself = create_node(my_addr, port);
91
  if (myself == NULL) {
92
    fprintf(stderr, "Error creating my socket (%s:%d)!\n", my_addr, port);
93
  }
94
  fprintf(stderr, "My sock: %d\n", myself->fd);
95

    
96
  res = bind(myself->fd, (struct sockaddr *)&myself->addr, sizeof(struct sockaddr_in));
97
  if (res < 0) {
98
    /* bind failed: not a local address... Just close the socket! */
99
    close(myself->fd);
100
    free(myself);
101

    
102
    return NULL;
103
  }
104

    
105
  return myself;
106
}
107

    
108
void bind_msg_type (uint8_t msgtype)
109
{
110
}
111

    
112
int send_to_peer(const struct nodeID *from, struct nodeID *to, const uint8_t *buffer_ptr, int buffer_size)
113
{
114
  static struct msghdr msg;
115
  static uint8_t my_hdr;
116
  struct iovec iov[2];
117
  int res;
118

    
119
  iov[0].iov_base = &my_hdr;
120
  iov[0].iov_len = 1;
121
  msg.msg_name = &to->addr;
122
  msg.msg_namelen = sizeof(struct sockaddr_in);
123
  msg.msg_iovlen = 2;
124
  msg.msg_iov = iov;
125
  
126
  do {
127
    iov[1].iov_base = buffer_ptr;
128
    if (buffer_size > 1024 * 60) {
129
      iov[1].iov_len = 1024 * 60;
130
      my_hdr = 0;
131
    } else {
132
      iov[1].iov_len = buffer_size;
133
      my_hdr = 1;
134
    }
135
    buffer_size -= iov[1].iov_len;
136
    buffer_ptr += iov[1].iov_len;
137
    res = sendmsg(from->fd, &msg, 0);
138
  } while (buffer_size > 0);
139

    
140
  return res;
141
}
142

    
143
int recv_from_peer(const struct nodeID *local, struct nodeID **remote, uint8_t *buffer_ptr, int buffer_size)
144
{
145
  int res, recv;
146
  struct sockaddr_in raddr;
147
  static struct msghdr msg;
148
  static uint8_t my_hdr;
149
  struct iovec iov[2];
150

    
151
  iov[0].iov_base = &my_hdr;
152
  iov[0].iov_len = 1;
153
  msg.msg_name = &raddr;
154
  msg.msg_namelen = sizeof(struct sockaddr_in);
155
  msg.msg_iovlen = 2;
156
  msg.msg_iov = iov;
157

    
158
  *remote = malloc(sizeof(struct nodeID));
159
  if (*remote == NULL) {
160
    return -1;
161
  }
162

    
163
  recv = 0;
164
  do {
165
    iov[1].iov_base = buffer_ptr;
166
    if (buffer_size > 1024 * 60) {
167
      iov[1].iov_len = 1024 * 60;
168
    } else {
169
      iov[1].iov_len = buffer_size;
170
    }
171
    buffer_size -= iov[1].iov_len;
172
    buffer_ptr += iov[1].iov_len;
173
    res = recvmsg(local->fd, &msg, 0);
174
    recv += (res - 1);
175
  } while ((my_hdr == 0) && (buffer_size > 0));
176
  memcpy(&(*remote)->addr, &raddr, msg.msg_namelen);
177
  (*remote)->fd = -1;
178

    
179
  return recv;
180
}
181

    
182
const char *node_addr(const struct nodeID *s)
183
{
184
  static char addr[256];
185

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

    
188
  return addr;
189
}
190

    
191
struct nodeID *nodeid_dup(struct nodeID *s)
192
{
193
  struct nodeID *res;
194

    
195
  res = malloc(sizeof(struct nodeID));
196
  if (res != NULL) {
197
    memcpy(res, s, sizeof(struct nodeID));
198
  }
199

    
200
  return res;
201
}
202
int nodeid_equal(const struct nodeID *s1, const struct nodeID *s2)
203
{
204
  return (memcmp(&s1->addr, &s2->addr, sizeof(struct sockaddr_in)) == 0);
205
}
206

    
207
int nodeid_dump(uint8_t *b, const struct nodeID *s, size_t max_write_size)
208
{
209
  if (max_write_size < sizeof(struct sockaddr_in)) return -1;
210

    
211
  memcpy(b, &s->addr, sizeof(struct sockaddr_in));
212

    
213
  return sizeof(struct sockaddr_in);
214
}
215

    
216
struct nodeID *nodeid_undump(const uint8_t *b, int *len)
217
{
218
  struct nodeID *res;
219
  res = malloc(sizeof(struct nodeID));
220
  if (res != NULL) {
221
    memcpy(&res->addr, b, sizeof(struct sockaddr_in));
222
  }
223
  *len = sizeof(struct sockaddr_in);
224

    
225
  return res;
226
}
227

    
228
void nodeid_free(struct nodeID *s)
229
{
230
  free(s);
231
}
232