Statistics
| Branch: | Revision:

grapes / som / net_helper.c @ 92bdbfcd

History | View | Annotate | Download (4.31 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, fd_set *user_fds)
25
{
26
  fd_set fds;
27
  int res;
28

    
29
  FD_ZERO(&fds);
30
  if (user_fds == NULL) {
31
    user_fds = &fds;
32
  }
33
  FD_SET(s->fd, user_fds);
34
  res = select(s->fd + 1, user_fds, NULL, NULL, tout);
35
  if (res <= 0) {
36
    return res;
37
  }
38
  if (FD_ISSET(s->fd, &fds)) {
39
    return 1;
40
  }
41

    
42
  return 2;
43
}
44

    
45
struct nodeID *create_node(const char *IPaddr, int port)
46
{
47
  struct nodeID *s;
48
  int res;
49

    
50
  s = malloc(sizeof(struct nodeID));
51
  memset(s, 0, sizeof(struct nodeID));
52
  s->addr.sin_family = AF_INET;
53
  s->addr.sin_port = htons(port);
54
  res = inet_aton(IPaddr, &s->addr.sin_addr);
55
  if (res == 0) {
56
    free(s);
57

    
58
    return NULL;
59
  }
60

    
61
  s->fd = socket(AF_INET, SOCK_DGRAM, 0);
62
  if (s->fd < 0) {
63
    free(s);
64
    
65
    return NULL;
66
  }
67

    
68
  return s;
69
}
70

    
71
struct nodeID *net_helper_init(const char *my_addr, int port)
72
{
73
  int res;
74
  struct nodeID *myself;
75

    
76
  myself = create_node(my_addr, port);
77
  if (myself == NULL) {
78
    fprintf(stderr, "Error creating my socket (%s:%d)!\n", my_addr, port);
79
  }
80
  fprintf(stderr, "My sock: %d\n", myself->fd);
81

    
82
  res = bind(myself->fd, (struct sockaddr *)&myself->addr, sizeof(struct sockaddr_in));
83
  if (res < 0) {
84
    /* bind failed: not a local address... Just close the socket! */
85
    close(myself->fd);
86
    free(myself);
87

    
88
    return NULL;
89
  }
90

    
91
  return myself;
92
}
93

    
94
void bind_msg_type (uint8_t msgtype)
95
{
96
}
97

    
98
int send_to_peer(const struct nodeID *from, struct nodeID *to, const uint8_t *buffer_ptr, int buffer_size)
99
{
100
  static struct msghdr msg;
101
  static uint8_t my_hdr;
102
  struct iovec iov[2];
103
  int res;
104

    
105
  iov[0].iov_base = &my_hdr;
106
  iov[0].iov_len = 1;
107
  msg.msg_name = &to->addr;
108
  msg.msg_namelen = sizeof(struct sockaddr_in);
109
  msg.msg_iovlen = 2;
110
  msg.msg_iov = iov;
111
  
112
  do {
113
    iov[1].iov_base = buffer_ptr;
114
    if (buffer_size > 1024 * 60) {
115
      iov[1].iov_len = 1024 * 60;
116
      my_hdr = 0;
117
    } else {
118
      iov[1].iov_len = buffer_size;
119
      my_hdr = 1;
120
    }
121
    buffer_size -= iov[1].iov_len;
122
    buffer_ptr += iov[1].iov_len;
123
    res = sendmsg(from->fd, &msg, 0);
124
  } while (buffer_size > 0);
125

    
126
  return res;
127
}
128

    
129
int recv_from_peer(const struct nodeID *local, struct nodeID **remote, uint8_t *buffer_ptr, int buffer_size)
130
{
131
  int res, recv;
132
  struct sockaddr_in raddr;
133
  static struct msghdr msg;
134
  static uint8_t my_hdr;
135
  struct iovec iov[2];
136

    
137
  iov[0].iov_base = &my_hdr;
138
  iov[0].iov_len = 1;
139
  msg.msg_name = &raddr;
140
  msg.msg_namelen = sizeof(struct sockaddr_in);
141
  msg.msg_iovlen = 2;
142
  msg.msg_iov = iov;
143

    
144
  *remote = malloc(sizeof(struct nodeID));
145
  if (*remote == NULL) {
146
    return -1;
147
  }
148

    
149
  recv = 0;
150
  do {
151
    iov[1].iov_base = buffer_ptr;
152
    if (buffer_size > 1024 * 60) {
153
      iov[1].iov_len = 1024 * 60;
154
    } else {
155
      iov[1].iov_len = buffer_size;
156
    }
157
    buffer_size -= iov[1].iov_len;
158
    buffer_ptr += iov[1].iov_len;
159
    res = recvmsg(local->fd, &msg, 0);
160
    recv += (res - 1);
161
  } while ((my_hdr == 0) && (buffer_size > 0));
162
  memcpy(&(*remote)->addr, &raddr, msg.msg_namelen);
163
  (*remote)->fd = -1;
164

    
165
  return recv;
166
}
167

    
168
const char *node_addr(const struct nodeID *s)
169
{
170
  static char addr[256];
171

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

    
174
  return addr;
175
}
176

    
177
struct nodeID *nodeid_dup(struct nodeID *s)
178
{
179
  struct nodeID *res;
180

    
181
  res = malloc(sizeof(struct nodeID));
182
  if (res != NULL) {
183
    memcpy(res, s, sizeof(struct nodeID));
184
  }
185

    
186
  return res;
187
}
188
int nodeid_equal(const struct nodeID *s1, const struct nodeID *s2)
189
{
190
  return (memcmp(&s1->addr, &s2->addr, sizeof(struct sockaddr_in)) == 0);
191
}
192

    
193
int nodeid_dump(uint8_t *b, const struct nodeID *s)
194
{
195
  memcpy(b, &s->addr, sizeof(struct sockaddr_in));
196

    
197
  return sizeof(struct sockaddr_in);
198
}
199

    
200
struct nodeID *nodeid_undump(const uint8_t *b, int *len)
201
{
202
  struct nodeID *res;
203
  res = malloc(sizeof(struct nodeID));
204
  if (res != NULL) {
205
    memcpy(&res->addr, b, sizeof(struct sockaddr_in));
206
  }
207
  *len = sizeof(struct sockaddr_in);
208

    
209
  return res;
210
}
211

    
212
void nodeid_free(struct nodeID *s)
213
{
214
  free(s);
215
}
216