Annotation of libaitrpc/src/blob.c, revision 1.1.2.13
1.1.2.1 misho 1: #include "global.h"
2:
3:
1.1.2.2 misho 4: /*
1.1.2.4 misho 5: * rpc_srv_blobCreate() Create map blob to memory region and return object
6: * @srv = RPC Server instance
7: * @len = BLOB length object
8: * return: NULL error or !=NULL allocated BLOB object
9: */
10: inline rpc_blob_t *
11: rpc_srv_blobCreate(rpc_srv_t * __restrict srv, int len)
12: {
13: rpc_blob_t *blob = NULL;
14: char szFName[MAXPATHLEN];
15: int f;
1.1.2.7 misho 16: u_int rnd;
17:
18: srandomdev();
19: srandom(getpid() ^ time(NULL));
20: again:
21: rnd = random() % UINT_MAX;
1.1.2.4 misho 22:
23: memset(szFName, 0, MAXPATHLEN);
1.1.2.7 misho 24: snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, rnd);
25: f = open(szFName, O_CREAT | O_EXCL | O_RDWR, 0600);
1.1.2.4 misho 26: if (f == -1) {
1.1.2.7 misho 27: if (errno == EEXIST)
28: goto again;
29:
1.1.2.4 misho 30: LOGERR;
31: return NULL;
32: }
33: if (lseek(f, len - 1, SEEK_SET) == -1) {
34: LOGERR;
35: close(f);
36: unlink(szFName);
37: return NULL;
38: } else
39: write(f, "", 1);
40:
41: blob = malloc(sizeof(rpc_blob_t));
42: if (!blob) {
43: LOGERR;
44: close(f);
45: unlink(szFName);
46: return NULL;
47: }
48:
49: blob->blob_data = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
50: if (blob->blob_data == MAP_FAILED) {
51: LOGERR;
52: free(blob);
53: close(f);
54: unlink(szFName);
55: return NULL;
56: } else
57: close(f);
58:
59: blob->blob_len = len;
1.1.2.7 misho 60: blob->blob_var = rnd;
1.1.2.4 misho 61: return blob;
62: }
63:
64: /*
1.1.2.2 misho 65: * rpc_srv_blobMap() Map blob to memory region
66: * @srv = RPC Server instance
67: * @blob = Map to this BLOB element
68: * return: -1 error or 0 ok
69: */
70: inline int
71: rpc_srv_blobMap(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
72: {
73: int f;
74: char szFName[MAXPATHLEN];
75:
76: if (!blob) {
77: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
78: return -1;
79: }
80:
81: memset(szFName, 0, MAXPATHLEN);
82: snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, blob->blob_var);
1.1.2.8 misho 83: f = open(szFName, O_RDWR);
1.1.2.2 misho 84: if (f == -1) {
85: LOGERR;
86: return -1;
87: }
88:
1.1.2.12 misho 89: blob->blob_data = mmap(NULL, blob->blob_len, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
1.1.2.2 misho 90: if (blob->blob_data == MAP_FAILED) {
91: LOGERR;
92: close(f);
93: blob->blob_data = NULL;
94: return -1;
95: } else {
96: close(f);
1.1.2.4 misho 97:
1.1.2.12 misho 98: madvise(blob->blob_data, blob->blob_len, MADV_SEQUENTIAL);
1.1.2.2 misho 99: }
100:
101: return 0;
102: }
103:
104: /*
105: * rpc_srv_blobUnmap() Unmap blob memory region
106: * @blob = Mapped BLOB element
107: * return: none
108: */
109: inline void
110: rpc_srv_blobUnmap(rpc_blob_t * __restrict blob)
111: {
112: if (!blob || !blob->blob_data)
113: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
114: else {
115: munmap(blob->blob_data, blob->blob_len);
116: blob->blob_data = NULL;
117: }
118: }
119:
120: /*
121: * rpc_srv_blobFree() Free blob from disk & memory
122: * @srv = RPC Server instance
123: * @blob = Mapped BLOB element
124: * return: -1 error or 0 ok
125: */
126: inline int
127: rpc_srv_blobFree(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
128: {
129: char szFName[MAXPATHLEN];
130:
131: if (!blob) {
132: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
133: return -1;
134: }
135:
136: if (blob->blob_data)
137: rpc_srv_blobUnmap(blob);
138:
139: memset(szFName, 0, MAXPATHLEN);
140: snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, blob->blob_var);
141: if (remove(szFName) == -1) {
142: LOGERR;
143: return -1;
144: }
145:
146: return 0;
147: }
148:
149: // ------------------------------------------------------------
150:
1.1.2.3 misho 151: /*
152: * rpc_srv_sendBLOB() Send mapped BLOB to client
153: * @cli = Client instance
154: * @blob = Mapped BLOB element
155: * return: -1 error, 0 ok
156: */
1.1.2.2 misho 157: int
1.1.2.3 misho 158: rpc_srv_sendBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
1.1.2.2 misho 159: {
1.1.2.3 misho 160: int ret, len;
161: uint8_t *pos;
1.1.2.2 misho 162:
1.1.2.3 misho 163: if (!cli || !blob || !blob->blob_data) {
1.1.2.2 misho 164: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
165: return -1;
166: }
167:
1.1.2.3 misho 168: for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len)
169: if ((len = send(cli->cli_sock, pos, ret > BLOBSIZ ? BLOBSIZ : ret, 0)) == -1) {
170: LOGERR;
171: return -1;
172: }
1.1.2.2 misho 173:
1.1.2.3 misho 174: return ret;
175: }
176:
177: /*
178: * rpc_srv_recvBLOB() Receive BLOB from client
179: * @cli = Client instance
1.1.2.4 misho 180: * @blob = Mapped BLOB element
181: * return: -1 error, 0 ok, >0 unreceived data from client, may be error?
1.1.2.3 misho 182: */
183: int
1.1.2.4 misho 184: rpc_srv_recvBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
1.1.2.3 misho 185: {
186: int ret, len;
187: uint8_t *pos;
1.1.2.4 misho 188: fd_set fds;
189: struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.3 misho 190:
1.1.2.4 misho 191: if (!cli || !blob || !blob->blob_data) {
1.1.2.3 misho 192: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
193: return -1;
1.1.2.4 misho 194: }
195:
196: for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len) {
197: FD_ZERO(&fds);
198: FD_SET(cli->cli_sock, &fds);
199: len = select(cli->cli_sock + 1, &fds, NULL, NULL, &tv);
200: if (len < 1) {
201: LOGERR;
202: return -1;
203: }
1.1.2.3 misho 204:
1.1.2.4 misho 205: if ((len = recv(cli->cli_sock, pos, BLOBSIZ, 0)) == -1) {
206: LOGERR;
207: return -1;
208: }
209: }
1.1.2.3 misho 210:
211: return ret;
1.1.2.2 misho 212: }
1.1.2.5 misho 213:
214: // ------------------------------------------------------------
215:
216: /*
217: * rpc_cli_sendBLOB() Send BLOB to server
218: * @cli = Client instance
219: * @var = BLOB variable
220: * @data = BLOB data
1.1.2.6 misho 221: * return: -1 error, 0 ok, 1 remote error
1.1.2.5 misho 222: */
223: int
224: rpc_cli_sendBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void * __restrict data)
225: {
226: int ret, len;
227: uint8_t *pos;
1.1.2.6 misho 228: struct tagBLOBHdr hdr;
229: fd_set fds;
230: struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.5 misho 231:
232: if (!cli || !var || !data) {
233: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
234: return -1;
235: }
236:
1.1.2.6 misho 237: memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
238: hdr.hdr_cmd = set;
1.1.2.10 misho 239: hdr.hdr_var = 0;
1.1.2.11 misho 240: hdr.hdr_ret = 0;
1.1.2.6 misho 241: hdr.hdr_len = var->val_len;
242: if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
243: LOGERR;
244: return -1;
245: }
246:
1.1.2.5 misho 247: for (ret = var->val_len, pos = data; ret > 0; ret -= len, pos += len)
248: if ((len = send(cli->cli_sock, pos, ret > BLOBSIZ ? BLOBSIZ : ret, 0)) == -1) {
249: LOGERR;
250: return -1;
251: }
252:
1.1.2.6 misho 253: FD_ZERO(&fds);
254: FD_SET(cli->cli_sock, &fds);
255: switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
256: case -1:
257: LOGERR;
258: return -1;
259: case 0:
260: rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
261: return -1;
262: }
1.1.2.10 misho 263: if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
1.1.2.6 misho 264: LOGERR;
265: return -1;
266: }
1.1.2.7 misho 267: if (hdr.hdr_cmd != error) {
268: if (hdr.hdr_len != var->val_len) {
269: rpc_SetErr(EBADMSG, "Error:: Bad return length packet ...\n");
270: return -1;
271: }
272:
1.1.2.10 misho 273: var->val.blob = hdr.hdr_var;
1.1.2.7 misho 274: }
1.1.2.6 misho 275:
276: return hdr.hdr_cmd == error;
1.1.2.5 misho 277: }
278:
279: /*
280: * rpc_cli_recvBLOB() Receive BLOB from server
281: * @cli = Client instance
282: * @var = BLOB variable
283: * @data = BLOB data, must be free after use!
1.1.2.10 misho 284: * return: -1 error, 0 ok, 1 remote error
1.1.2.5 misho 285: */
286: int
287: rpc_cli_recvBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void ** data)
288: {
289: int ret, len;
290: uint8_t *pos;
291: fd_set fds;
292: struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.10 misho 293: struct tagBLOBHdr hdr;
1.1.2.5 misho 294:
295: if (!cli || !var || !data) {
296: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
297: return -1;
298: }
299:
300: *data = malloc(var->val_len);
301: if (!*data) {
302: LOGERR;
303: return -1;
304: } else
305: memset(*data, 0, var->val_len);
306:
1.1.2.10 misho 307: memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
308: hdr.hdr_cmd = get;
309: hdr.hdr_var = (uint32_t) RPC_GET_BLOB(var);
1.1.2.11 misho 310: hdr.hdr_ret = 0;
1.1.2.10 misho 311: hdr.hdr_len = 0;
312: if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
313: LOGERR;
314: free(*data);
315: *data = NULL;
316: return -1;
317: }
318:
1.1.2.5 misho 319: for (ret = var->val_len, pos = *data; ret > 0; ret -= len, pos += len) {
320: FD_ZERO(&fds);
321: FD_SET(cli->cli_sock, &fds);
322: len = select(cli->cli_sock + 1, &fds, NULL, NULL, &tv);
323: if (len < 1) {
324: LOGERR;
325: free(*data);
326: *data = NULL;
327: return -1;
328: }
329:
330: if ((len = recv(cli->cli_sock, pos, BLOBSIZ, 0)) == -1) {
331: LOGERR;
332: free(*data);
333: *data = NULL;
334: return -1;
335: }
336: }
337:
1.1.2.10 misho 338: FD_ZERO(&fds);
339: FD_SET(cli->cli_sock, &fds);
340: switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
341: case -1:
342: LOGERR;
343: free(*data);
344: *data = NULL;
345: return -1;
346: case 0:
347: rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
348: free(*data);
349: *data = NULL;
350: return -1;
351: }
352: if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
353: LOGERR;
354: free(*data);
355: *data = NULL;
356: return -1;
357: }
358: if (hdr.hdr_cmd != error) {
359: if (hdr.hdr_len != var->val_len) {
360: rpc_SetErr(EBADMSG, "Error:: Bad return length packet ...\n");
361: free(*data);
362: *data = NULL;
363: return -1;
364: }
365: }
366:
367: return hdr.hdr_cmd == error;
1.1.2.5 misho 368: }
1.1.2.13! misho 369:
! 370: /*
! 371: * rpc_cli_delBLOB() Delete BLOB from server
! 372: * @cli = Client instance
! 373: * @var = BLOB variable
! 374: * return: -1 error, 0 ok, 1 remote error
! 375: */
! 376: int
! 377: rpc_cli_delBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var)
! 378: {
! 379: struct tagBLOBHdr hdr;
! 380: fd_set fds;
! 381: struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
! 382:
! 383: if (!cli || !var) {
! 384: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
! 385: return -1;
! 386: }
! 387:
! 388: memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
! 389: hdr.hdr_cmd = unset;
! 390: hdr.hdr_var = (uint32_t) RPC_GET_BLOB(var);
! 391: hdr.hdr_ret = 0;
! 392: hdr.hdr_len = 0;
! 393: if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
! 394: LOGERR;
! 395: return -1;
! 396: }
! 397:
! 398: FD_ZERO(&fds);
! 399: FD_SET(cli->cli_sock, &fds);
! 400: switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
! 401: case -1:
! 402: LOGERR;
! 403: return -1;
! 404: case 0:
! 405: rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
! 406: return -1;
! 407: }
! 408: if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
! 409: LOGERR;
! 410: return -1;
! 411: }
! 412:
! 413: return hdr.hdr_cmd == error;
! 414: }
! 415:
! 416: /*
! 417: * rpc_cli_getBLOB() Receive BLOB from server and Delete after that
! 418: * @cli = Client instance
! 419: * @var = BLOB variable
! 420: * @data = BLOB data, must be free after use!
! 421: * return: -1 error, 0 ok, 1 remote error
! 422: */
! 423: inline int
! 424: rpc_cli_getBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void ** data)
! 425: {
! 426: int ret;
! 427:
! 428: ret = rpc_cli_recvBLOB(cli, var, data);
! 429: ret |= rpc_cli_delBLOB(cli, var) > 0 ? 2 : 0;
! 430:
! 431: return ret;
! 432: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>