4 #include <sys/types.h> /* socket defines */
5 #include <sys/socket.h> /* socket functions */
6 #include <stdlib.h> /* malloc() */
7 #include <stdint.h> /* uint32_t and friends */
8 #include <arpa/inet.h> /* htonls() and friends */
9 #include <string.h> /* memcpy() */
10 #include <unistd.h> /* close() */
12 #include <netinet/sctp.h> /* SCTP stuff */
13 #include <netdb.h> /* gethostbyname() */
16 #include "net-const.h"
21 /* Used internally to really add the server once we have an IP address. */
22 static int add_sctp_server_addr(nmdb_t
*db
, in_addr_t
*inetaddr
, int port
)
25 struct nmdb_srv
*newsrv
, *newarray
;
27 fd
= socket(AF_INET
, SOCK_SEQPACKET
, IPPROTO_SCTP
);
31 /* Disable Nagle algorithm because we often send small
32 * packets. Huge gain in performance. */
34 if (setsockopt(fd
, IPPROTO_SCTP
, SCTP_NODELAY
, &rv
, sizeof(rv
)) < 0 ) {
39 newarray
= realloc(db
->servers
,
40 sizeof(struct nmdb_srv
) * (db
->nservers
+ 1));
41 if (newarray
== NULL
) {
46 db
->servers
= newarray
;
50 port
= SCTP_SERVER_PORT
;
52 newsrv
= &(db
->servers
[db
->nservers
- 1]);
55 newsrv
->info
.in
.srvsa
.sin_family
= AF_INET
;
56 newsrv
->info
.in
.srvsa
.sin_port
= htons(port
);
57 newsrv
->info
.in
.srvsa
.sin_addr
.s_addr
= *inetaddr
;
58 newsrv
->info
.in
.srvlen
= sizeof(struct sockaddr_in
);
60 newsrv
->type
= SCTP_CONN
;
62 /* keep the list sorted by port, so we can do a reliable selection */
63 qsort(db
->servers
, db
->nservers
, sizeof(struct nmdb_srv
),
69 /* Same as nmdb_add_tcp_server() but for SCTP. */
70 int nmdb_add_sctp_server(nmdb_t
*db
, const char *addr
, int port
)
76 /* We try to resolve and then pass it to add_sctp_server_addr(). */
77 rv
= inet_pton(AF_INET
, addr
, &ia
);
79 he
= gethostbyname(addr
);
83 ia
.s_addr
= *( (in_addr_t
*) (he
->h_addr_list
[0]) );
86 return add_sctp_server_addr(db
, &(ia
.s_addr
), port
);
89 int sctp_srv_send(struct nmdb_srv
*srv
, unsigned char *buf
, size_t bsize
)
92 rv
= sendto(srv
->fd
, buf
, bsize
, 0,
93 (struct sockaddr
*) &(srv
->info
.in
.srvsa
),
100 /* Used internally to get and parse replies from the server. */
101 uint32_t sctp_get_rep(struct nmdb_srv
*srv
,
102 unsigned char *buf
, size_t bsize
,
103 unsigned char **payload
, size_t *psize
)
108 rv
= recv(srv
->fd
, buf
, bsize
, 0);
113 id
= * (uint32_t *) buf
;
115 reply
= * ((uint32_t *) buf
+ 1);
116 reply
= ntohl(reply
);
122 if (payload
!= NULL
) {
123 *payload
= buf
+ 4 + 4;
130 /* Stubs to use when SCTP is not enabled. */
136 int nmdb_add_sctp_server(nmdb_t
*db
, const char *addr
, int port
)
141 int sctp_srv_send(struct nmdb_srv
*srv
, unsigned char *buf
, size_t bsize
)
146 uint32_t sctp_get_rep(struct nmdb_srv
*srv
,
147 unsigned char *buf
, size_t bsize
,
148 unsigned char **payload
, size_t *psize
)
153 #endif /* ENABLE_SCTP */