ucspi-ssl  0.99e
TLS encryption for IPv6 communication
cdb_make.c
Go to the documentation of this file.
1 /* Public domain. */
2 
3 #include "seek.h"
4 #include "error.h"
5 #include "alloc.h"
6 #include "cdb.h"
7 #include "cdb_make.h"
8 
9 int cdb_make_start(struct cdb_make *c,int fd)
10 {
11  c->head = 0;
12  c->split = 0;
13  c->hash = 0;
14  c->numentries = 0;
15  c->fd = fd;
16  c->pos = sizeof c->final;
17  buffer_init(&c->b,buffer_unixwrite,fd,c->bspace,sizeof c->bspace);
18  return seek_set(fd,c->pos);
19 }
20 
21 static int posplus(struct cdb_make *c,uint32 len)
22 {
23  uint32 newpos = c->pos + len;
24  if (newpos < len) { errno = error_nomem; return -1; }
25  c->pos = newpos;
26  return 0;
27 }
28 
29 int cdb_make_addend(struct cdb_make *c,unsigned int keylen,unsigned int datalen,uint32 h)
30 {
31  struct cdb_hplist *head;
32 
33  head = c->head;
34  if (!head || (head->num >= CDB_HPLIST)) {
35  head = (struct cdb_hplist *) alloc(sizeof(struct cdb_hplist));
36  if (!head) return -1;
37  head->num = 0;
38  head->next = c->head;
39  c->head = head;
40  }
41  head->hp[head->num].h = h;
42  head->hp[head->num].p = c->pos;
43  ++head->num;
44  ++c->numentries;
45  if (posplus(c,8) == -1) return -1;
46  if (posplus(c,keylen) == -1) return -1;
47  if (posplus(c,datalen) == -1) return -1;
48  return 0;
49 }
50 
51 int cdb_make_addbegin(struct cdb_make *c,unsigned int keylen,unsigned int datalen)
52 {
53  char buf[8];
54 
55  if (keylen > 0xffffffff) { errno = error_nomem; return -1; }
56  if (datalen > 0xffffffff) { errno = error_nomem; return -1; }
57 
58  uint32_pack(buf,keylen);
59  uint32_pack(buf + 4,datalen);
60  if (buffer_putalign(&c->b,buf,8) == -1) return -1;
61  return 0;
62 }
63 
64 int cdb_make_add(struct cdb_make *c,const char *key,unsigned int keylen,const char *data,unsigned int datalen)
65 {
66  if (cdb_make_addbegin(c,keylen,datalen) == -1) return -1;
67  if (buffer_putalign(&c->b,key,keylen) == -1) return -1;
68  if (buffer_putalign(&c->b,data,datalen) == -1) return -1;
69  return cdb_make_addend(c,keylen,datalen,cdb_hash(key,keylen));
70 }
71 
72 int cdb_make_finish(struct cdb_make *c)
73 {
74  char buf[8];
75  int i;
76  uint32 len;
77  uint32 u;
78  uint32 memsize;
79  uint32 count;
80  uint32 where;
81  struct cdb_hplist *x;
82  struct cdb_hp *hp;
83 
84  for (i = 0;i < 256;++i)
85  c->count[i] = 0;
86 
87  for (x = c->head;x;x = x->next) {
88  i = x->num;
89  while (i--)
90  ++c->count[255 & x->hp[i].h];
91  }
92 
93  memsize = 1;
94  for (i = 0;i < 256;++i) {
95  u = c->count[i] * 2;
96  if (u > memsize)
97  memsize = u;
98  }
99 
100  memsize += c->numentries; /* no overflow possible up to now */
101  u = (uint32) 0 - (uint32) 1;
102  u /= sizeof(struct cdb_hp);
103  if (memsize > u) { errno = error_nomem; return -1; }
104 
105  c->split = (struct cdb_hp *) alloc(memsize * sizeof(struct cdb_hp));
106  if (!c->split) return -1;
107 
108  c->hash = c->split + c->numentries;
109 
110  u = 0;
111  for (i = 0;i < 256;++i) {
112  u += c->count[i]; /* bounded by numentries, so no overflow */
113  c->start[i] = u;
114  }
115 
116  for (x = c->head;x;x = x->next) {
117  i = x->num;
118  while (i--)
119  c->split[--c->start[255 & x->hp[i].h]] = x->hp[i];
120  }
121 
122  for (i = 0;i < 256;++i) {
123  count = c->count[i];
124 
125  len = count + count; /* no overflow possible */
126  uint32_pack(c->final + 8 * i,c->pos);
127  uint32_pack(c->final + 8 * i + 4,len);
128 
129  for (u = 0;u < len;++u)
130  c->hash[u].h = c->hash[u].p = 0;
131 
132  hp = c->split + c->start[i];
133  for (u = 0;u < count;++u) {
134  where = (hp->h >> 8) % len;
135  while (c->hash[where].p)
136  if (++where == len)
137  where = 0;
138  c->hash[where] = *hp++;
139  }
140 
141  for (u = 0;u < len;++u) {
142  uint32_pack(buf,c->hash[u].h);
143  uint32_pack(buf + 4,c->hash[u].p);
144  if (buffer_putalign(&c->b,buf,8) == -1) return -1;
145  if (posplus(c,8) == -1) return -1;
146  }
147  }
148 
149  if (buffer_flush(&c->b) == -1) return -1;
150  if (seek_begin(c->fd) == -1) return -1;
151  return buffer_putflush(&c->b,c->final,sizeof c->final);
152 }
uint32 count[256]
Definition: cdb_make.h:22
struct cdb_hp * split
Definition: cdb_make.h:25
struct cdb_hplist * next
Definition: cdb_make.h:15
char * alloc(unsigned int n)
Definition: alloc.c:15
struct cdb_hp hp[CDB_HPLIST]
Definition: cdb_make.h:14
int buffer_unixwrite(int, const char *, unsigned int)
Definition: buffer_write.c:6
void uint32_pack(char s[4], uint32 u)
Definition: uint32_pack.c:3
uint32 start[256]
Definition: cdb_make.h:23
char buf[SSL_NAME_LEN]
Definition: sslhandle.c:125
int cdb_make_add(struct cdb_make *c, const char *key, unsigned int keylen, const char *data, unsigned int datalen)
Definition: cdb_make.c:64
int cdb_make_start(struct cdb_make *c, int fd)
Definition: cdb_make.c:9
struct cdb_hplist * head
Definition: cdb_make.h:24
void buffer_init(buffer *s, int(*op)(), int fd, char *buf, unsigned int len)
Definition: buffer.c:5
int fd
Definition: cdb_make.h:30
int buffer_putalign(buffer *, const char *, unsigned int)
Definition: buffer_put.c:35
int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen)
Definition: cdb_make.c:51
int error_nomem
Definition: error.c:15
int seek_set(int, seek_pos)
Definition: seek_set.c:9
struct cdb_hp * hash
Definition: cdb_make.h:26
char final[2048]
Definition: cdb_make.h:21
buffer b
Definition: cdb_make.h:28
#define CDB_HPLIST
Definition: cdb_make.h:9
uint32 numentries
Definition: cdb_make.h:27
#define seek_begin(fd)
Definition: seek.h:15
int buffer_putflush(buffer *, const char *, unsigned int)
Definition: buffer_put.c:71
uint32 p
Definition: cdb_make.h:11
int num
Definition: cdb_make.h:16
int cdb_make_finish(struct cdb_make *c)
Definition: cdb_make.c:72
int cdb_make_addend(struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h)
Definition: cdb_make.c:29
uint32 h
Definition: cdb_make.h:11
char bspace[8192]
Definition: cdb_make.h:20
uint32 pos
Definition: cdb_make.h:29
int buffer_flush(buffer *)
Definition: buffer_put.c:25
uint32 cdb_hash(const char *, unsigned int)
Definition: cdb_hash.c:11