Annotation of libaitrpc/src/blob.c, revision 1.1.2.10
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: struct stat sb;
75: char szFName[MAXPATHLEN];
76:
77: if (!blob) {
78: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
79: return -1;
80: }
81:
82: memset(szFName, 0, MAXPATHLEN);
83: snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, blob->blob_var);
1.1.2.8 misho 84: f = open(szFName, O_RDWR);
1.1.2.2 misho 85: if (f == -1) {
86: LOGERR;
87: return -1;
88: }
89: if (fstat(f, &sb) == -1) {
90: LOGERR;
91: close(f);
92: return -1;
93: }
94:
1.1.2.8 misho 95: blob->blob_data = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
1.1.2.2 misho 96: if (blob->blob_data == MAP_FAILED) {
97: LOGERR;
98: close(f);
99: blob->blob_data = NULL;
100: return -1;
101: } else {
102: blob->blob_len = sb.st_size;
103: close(f);
1.1.2.4 misho 104:
105: madvise(blob->blob_data, sb.st_size, MADV_SEQUENTIAL);
1.1.2.2 misho 106: }
107:
108: return 0;
109: }
110:
111: /*
112: * rpc_srv_blobUnmap() Unmap blob memory region
113: * @blob = Mapped BLOB element
114: * return: none
115: */
116: inline void
117: rpc_srv_blobUnmap(rpc_blob_t * __restrict blob)
118: {
119: if (!blob || !blob->blob_data)
120: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
121: else {
122: munmap(blob->blob_data, blob->blob_len);
123: blob->blob_data = NULL;
124: blob->blob_len = 0;
125: }
126: }
127:
128: /*
129: * rpc_srv_blobFree() Free blob from disk & memory
130: * @srv = RPC Server instance
131: * @blob = Mapped BLOB element
132: * return: -1 error or 0 ok
133: */
134: inline int
135: rpc_srv_blobFree(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
136: {
137: char szFName[MAXPATHLEN];
138:
139: if (!blob) {
140: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
141: return -1;
142: }
143:
144: if (blob->blob_data)
145: rpc_srv_blobUnmap(blob);
146:
147: memset(szFName, 0, MAXPATHLEN);
148: snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, blob->blob_var);
149: if (remove(szFName) == -1) {
150: LOGERR;
151: return -1;
152: }
153:
154: return 0;
155: }
156:
157: // ------------------------------------------------------------
158:
1.1.2.3 misho 159: /*
160: * rpc_srv_sendBLOB() Send mapped BLOB to client
161: * @cli = Client instance
162: * @blob = Mapped BLOB element
163: * return: -1 error, 0 ok
164: */
1.1.2.2 misho 165: int
1.1.2.3 misho 166: rpc_srv_sendBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
1.1.2.2 misho 167: {
1.1.2.3 misho 168: int ret, len;
169: uint8_t *pos;
1.1.2.2 misho 170:
1.1.2.3 misho 171: if (!cli || !blob || !blob->blob_data) {
1.1.2.2 misho 172: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
173: return -1;
174: }
175:
1.1.2.3 misho 176: for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len)
177: if ((len = send(cli->cli_sock, pos, ret > BLOBSIZ ? BLOBSIZ : ret, 0)) == -1) {
178: LOGERR;
179: return -1;
180: }
1.1.2.2 misho 181:
1.1.2.3 misho 182: return ret;
183: }
184:
185: /*
186: * rpc_srv_recvBLOB() Receive BLOB from client
187: * @cli = Client instance
1.1.2.4 misho 188: * @blob = Mapped BLOB element
189: * return: -1 error, 0 ok, >0 unreceived data from client, may be error?
1.1.2.3 misho 190: */
191: int
1.1.2.4 misho 192: rpc_srv_recvBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
1.1.2.3 misho 193: {
194: int ret, len;
195: uint8_t *pos;
1.1.2.4 misho 196: fd_set fds;
197: struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.3 misho 198:
1.1.2.4 misho 199: if (!cli || !blob || !blob->blob_data) {
1.1.2.3 misho 200: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
201: return -1;
1.1.2.4 misho 202: }
203:
204: for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len) {
205: FD_ZERO(&fds);
206: FD_SET(cli->cli_sock, &fds);
207: len = select(cli->cli_sock + 1, &fds, NULL, NULL, &tv);
208: if (len < 1) {
209: LOGERR;
210: return -1;
211: }
1.1.2.3 misho 212:
1.1.2.4 misho 213: if ((len = recv(cli->cli_sock, pos, BLOBSIZ, 0)) == -1) {
214: LOGERR;
215: return -1;
216: }
217: }
1.1.2.3 misho 218:
219: return ret;
1.1.2.2 misho 220: }
1.1.2.5 misho 221:
222: // ------------------------------------------------------------
223:
224: /*
225: * rpc_cli_sendBLOB() Send BLOB to server
226: * @cli = Client instance
227: * @var = BLOB variable
228: * @data = BLOB data
1.1.2.6 misho 229: * return: -1 error, 0 ok, 1 remote error
1.1.2.5 misho 230: */
231: int
232: rpc_cli_sendBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void * __restrict data)
233: {
234: int ret, len;
235: uint8_t *pos;
1.1.2.6 misho 236: struct tagBLOBHdr hdr;
237: fd_set fds;
238: struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.5 misho 239:
240: if (!cli || !var || !data) {
241: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
242: return -1;
243: }
244:
1.1.2.6 misho 245: memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
246: hdr.hdr_cmd = set;
1.1.2.10! misho 247: hdr.hdr_var = 0;
1.1.2.6 misho 248: hdr.hdr_seq = 0;
249: hdr.hdr_len = var->val_len;
250: if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
251: LOGERR;
252: return -1;
253: }
254:
1.1.2.5 misho 255: for (ret = var->val_len, pos = data; ret > 0; ret -= len, pos += len)
256: if ((len = send(cli->cli_sock, pos, ret > BLOBSIZ ? BLOBSIZ : ret, 0)) == -1) {
257: LOGERR;
258: return -1;
259: }
260:
1.1.2.6 misho 261: FD_ZERO(&fds);
262: FD_SET(cli->cli_sock, &fds);
263: switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
264: case -1:
265: LOGERR;
266: return -1;
267: case 0:
268: rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
269: return -1;
270: }
1.1.2.10! misho 271: if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
1.1.2.6 misho 272: LOGERR;
273: return -1;
274: }
1.1.2.7 misho 275: if (hdr.hdr_cmd != error) {
276: if (hdr.hdr_len != var->val_len) {
277: rpc_SetErr(EBADMSG, "Error:: Bad return length packet ...\n");
278: return -1;
279: }
280:
1.1.2.10! misho 281: var->val.blob = hdr.hdr_var;
1.1.2.7 misho 282: }
1.1.2.6 misho 283:
284: return hdr.hdr_cmd == error;
1.1.2.5 misho 285: }
286:
287: /*
288: * rpc_cli_recvBLOB() Receive BLOB from server
289: * @cli = Client instance
290: * @var = BLOB variable
291: * @data = BLOB data, must be free after use!
1.1.2.10! misho 292: * return: -1 error, 0 ok, 1 remote error
1.1.2.5 misho 293: */
294: int
295: rpc_cli_recvBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void ** data)
296: {
297: int ret, len;
298: uint8_t *pos;
299: fd_set fds;
300: struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.10! misho 301: struct tagBLOBHdr hdr;
1.1.2.5 misho 302:
303: if (!cli || !var || !data) {
304: rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
305: return -1;
306: }
307:
308: *data = malloc(var->val_len);
309: if (!*data) {
310: LOGERR;
311: return -1;
312: } else
313: memset(*data, 0, var->val_len);
314:
1.1.2.10! misho 315: memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
! 316: hdr.hdr_cmd = get;
! 317: hdr.hdr_var = (uint32_t) RPC_GET_BLOB(var);
! 318: hdr.hdr_seq = 0;
! 319: hdr.hdr_len = 0;
! 320: if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
! 321: LOGERR;
! 322: free(*data);
! 323: *data = NULL;
! 324: return -1;
! 325: }
! 326:
1.1.2.5 misho 327: for (ret = var->val_len, pos = *data; ret > 0; ret -= len, pos += len) {
328: FD_ZERO(&fds);
329: FD_SET(cli->cli_sock, &fds);
330: len = select(cli->cli_sock + 1, &fds, NULL, NULL, &tv);
331: if (len < 1) {
332: LOGERR;
333: free(*data);
334: *data = NULL;
335: return -1;
336: }
337:
338: if ((len = recv(cli->cli_sock, pos, BLOBSIZ, 0)) == -1) {
339: LOGERR;
340: free(*data);
341: *data = NULL;
342: return -1;
343: }
344: }
345:
1.1.2.10! misho 346: FD_ZERO(&fds);
! 347: FD_SET(cli->cli_sock, &fds);
! 348: switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
! 349: case -1:
! 350: LOGERR;
! 351: free(*data);
! 352: *data = NULL;
! 353: return -1;
! 354: case 0:
! 355: rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
! 356: free(*data);
! 357: *data = NULL;
! 358: return -1;
! 359: }
! 360: if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
! 361: LOGERR;
! 362: free(*data);
! 363: *data = NULL;
! 364: return -1;
! 365: }
! 366: if (hdr.hdr_cmd != error) {
! 367: if (hdr.hdr_len != var->val_len) {
! 368: rpc_SetErr(EBADMSG, "Error:: Bad return length packet ...\n");
! 369: free(*data);
! 370: *data = NULL;
! 371: return -1;
! 372: }
! 373: }
! 374:
! 375: return hdr.hdr_cmd == error;
1.1.2.5 misho 376: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>