Statistics
| Branch: | Revision:

grapes / som / net_helper.c @ 41f12636

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

    
29
  FD_ZERO(&fds);
30
  FD_SET(s->fd, &fds);
31
  res = select(s->fd + 1, &fds, NULL, NULL, tout);
32
  if (FD_ISSET(s->fd, &fds)) {
33
    return 1;
34
  }
35

    
36
  return 0;
37
}
38

    
39
struct nodeID *create_node(const char *IPaddr, int port)
40
{
41
  struct nodeID *s;
42
  int res;
43

    
44
  s = malloc(sizeof(struct nodeID));
45
  memset(s, 0, sizeof(struct nodeID));
46
  s->addr.sin_family = AF_INET;
47
  s->addr.sin_port = htons(port);
48
  res = inet_aton(IPaddr, &s->addr.sin_addr);
49
  if (res == 0) {
50
    free(s);
51

    
52
    return NULL;
53
  }
54

    
55
  s->fd = socket(AF_INET, SOCK_DGRAM, 0);
56
  if (s->fd < 0) {
57
    free(s);
58
    
59
    return NULL;
60
  }
61

    
62
  return s;
63
}
64

    
65
struct nodeID *net_helper_init(const char *my_addr, int port)
66
{
67
  int res;
68
  struct nodeID *myself;
69

    
70
  myself = create_node(my_addr, port);
71
  if (myself == NULL) {
72
    fprintf(stderr, "Error creating my socket (%s:%d)!\n", my_addr, port);
73
  }
74
  fprintf(stderr, "My sock: %d\n", myself->fd);
75

    
76
  res = bind(myself->fd, (struct sockaddr *)&myself->addr, sizeof(struct sockaddr_in));
77
  if (res < 0) {
78
    /* bind failed: not a local address... Just close the socket! */
79
    close(myself->fd);
80
    free(myself);
81

    
82
    return NULL;
83
  }
84

    
85
  return myself;
86
}
87

    
88
void bind_msg_type (uint8_t msgtype)
89
{
90
}
91

    
92
int send_to_peer(const struct nodeID *from, struct nodeID *to, const uint8_t *buffer_ptr, int buffer_size)
93
{
94
  static struct msghdr msg;
95
  static uint8_t my_hdr;
96
  struct iovec iov[2];
97
  int res;
98

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

    
120
  return res;
121
}
122

    
123
int recv_from_peer(const struct nodeID *local, struct nodeID **remote, uint8_t *buffer_ptr, int buffer_size)
124
{
125
  int res, recv;
126
  struct sockaddr_in raddr;
127
  static struct msghdr msg;
128
  static uint8_t my_hdr;
129
  struct iovec iov[2];
130

    
131
  iov[0].iov_base = &my_hdr;
132
  iov[0].iov_len = 1;
133
  msg.msg_name = &raddr;
134
  msg.msg_namelen = sizeof(struct sockaddr_in);
135
  msg.msg_iovlen = 2;
136
  msg.msg_iov = iov;
137

    
138
  *remote = malloc(sizeof(struct nodeID));
139
  if (*remote == NULL) {
140
    return -1;
141
  }
142

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

    
159
  return recv;
160
}
161

    
162
const char *node_addr(const struct nodeID *s)
163
{
164
  static char addr[256];
165

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

    
168
  return addr;
169
}
170

    
171
struct nodeID *nodeid_dup(struct nodeID *s)
172
{
173
  struct nodeID *res;
174

    
175
  res = malloc(sizeof(struct nodeID));
176
  if (res != NULL) {
177
    memcpy(res, s, sizeof(struct nodeID));
178
  }
179

    
180
  return res;
181
}
182
int nodeid_equal(const struct nodeID *s1, const struct nodeID *s2)
183
{
184
  return (memcmp(&s1->addr, &s2->addr, sizeof(struct sockaddr_in)) == 0);
185
}
186

    
187
int nodeid_dump(uint8_t *b, const struct nodeID *s)
188
{
189
  memcpy(b, &s->addr, sizeof(struct sockaddr_in));
190

    
191
  return sizeof(struct sockaddr_in);
192
}
193

    
194
struct nodeID *nodeid_undump(const uint8_t *b, int *len)
195
{
196
  struct nodeID *res;
197
  res = malloc(sizeof(struct nodeID));
198
  if (res != NULL) {
199
    memcpy(&res->addr, b, sizeof(struct sockaddr_in));
200
  }
201
  *len = sizeof(struct sockaddr_in);
202

    
203
  return res;
204
}
205

    
206
void nodeid_free(struct nodeID *s)
207
{
208
  free(s);
209
}
210