Changeset 4629
- Timestamp:
- 02/14/07 23:17:09 (2 years ago)
- Files:
-
- libwired/trunk/libwired/base/wi-base.h (modified) (3 diffs)
- libwired/trunk/libwired/file/wi-file.c (modified) (1 diff)
- libwired/trunk/libwired/p7/wi-p7-base.h (modified) (1 diff)
- libwired/trunk/libwired/p7/wi-p7-crypto.c (modified) (9 diffs)
- libwired/trunk/libwired/p7/wi-p7-crypto.h (modified) (3 diffs)
- libwired/trunk/libwired/p7/wi-p7-message.h (modified) (1 diff)
- libwired/trunk/libwired/p7/wi-p7-private.h (modified) (1 diff)
- libwired/trunk/libwired/p7/wi-p7-socket.c (modified) (16 diffs)
- libwired/trunk/libwired/p7/wi-p7-socket.h (modified) (2 diffs)
- libwired/trunk/libwired/p7/wi-p7-spec.c (modified) (13 diffs)
- libwired/trunk/libwired/p7/wi-p7-spec.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
libwired/trunk/libwired/base/wi-base.h
r4556 r4629 60 60 #endif 61 61 62 #define _WI_STRINGIFY(s) #s63 #define WI_STRINGIFY(s) _WI_STRINGIFY(s)64 65 62 #if __LP64__ 66 63 #define WI_64 1 … … 68 65 typedef int64_t wi_integer_t; 69 66 typedef uint64_t wi_uinteger_t; 67 68 #define WI_INTEGER_MIN INT64_MIN 69 #define WI_INTEGER_MAX INT64_MAX 70 #define WI_UINTEGER_MAX UINT64_MAX 70 71 #else 71 72 #define WI_32 1 … … 73 74 typedef int32_t wi_integer_t; 74 75 typedef uint32_t wi_uinteger_t; 76 77 #define WI_INTEGER_MIN INT32_MIN 78 #define WI_INTEGER_MAX INT32_MAX 79 #define WI_UINTEGER_MAX UINT32_MAX 75 80 #endif 76 81 77 82 78 83 enum { 79 #if WI_32 80 WI_NOT_FOUND = 0x7FFFFFFF 81 #else 82 WI_NOT_FOUND = 0x7FFFFFFFFFFFFFFF 83 #endif 84 WI_NOT_FOUND = WI_INTEGER_MAX 84 85 }; 85 86 libwired/trunk/libwired/file/wi-file.c
r4623 r4629 72 72 #include <wired/wi-string.h> 73 73 74 #ifndef UINT_MAX75 #define UINT_MAX 4294967295U76 #endif77 78 74 #define _WI_FILE_ASSERT_OPEN(file) \ 79 75 WI_ASSERT((file)->fd >= 0, "%@ is not open", (file)) libwired/trunk/libwired/p7/wi-p7-base.h
r4623 r4629 34 34 typedef struct _wi_p7_spec wi_p7_spec_t; 35 35 36 #endif /* WI_ ARRAY_H */36 #endif /* WI_P7_BASE_H */ libwired/trunk/libwired/p7/wi-p7-crypto.c
r4627 r4629 51 51 static wi_string_t * _wi_p7_rsa_description(wi_runtime_instance_t *); 52 52 53 static wi_data_t * _wi_p7_rsa_public_key_data(wi_p7_rsa_t *); 54 53 55 static wi_runtime_id_t _wi_p7_rsa_runtime_id = WI_RUNTIME_ID_NULL; 54 56 static wi_runtime_class_t _wi_p7_rsa_runtime_class = { … … 119 121 120 122 121 wi_p7_rsa_t * wi_p7_rsa_init_with_ size(wi_p7_rsa_t *p7_rsa, wi_uinteger_t size) {123 wi_p7_rsa_t * wi_p7_rsa_init_with_bits(wi_p7_rsa_t *p7_rsa, wi_uinteger_t size) { 122 124 p7_rsa->rsa = RSA_generate_key(size, RSA_F4, NULL, NULL); 123 125 … … 128 130 } 129 131 132 p7_rsa->public_key_data = wi_retain(_wi_p7_rsa_public_key_data(p7_rsa)); 133 134 if(!p7_rsa->public_key_data) { 135 wi_release(p7_rsa); 136 137 return NULL; 138 } 139 130 140 return p7_rsa; 131 141 } … … 134 144 135 145 wi_p7_rsa_t * wi_p7_rsa_init_with_pem_file(wi_p7_rsa_t *p7_rsa, wi_string_t *path) { 136 unsigned char *buffer; 137 int length; 138 FILE *fp; 146 FILE *fp; 139 147 140 148 fp = fopen(wi_string_cstring(path), "r"); … … 150 158 p7_rsa->rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); 151 159 160 fclose(fp); 161 152 162 if(!p7_rsa->rsa) { 153 163 wi_error_set_openssl_error(); … … 158 168 } 159 169 160 buffer = NULL; 161 length = i2d_RSA_PUBKEY(p7_rsa->rsa, &buffer); 162 163 if(length <= 0) { 164 wi_error_set_openssl_error(); 165 170 p7_rsa->public_key_data = wi_retain(_wi_p7_rsa_public_key_data(p7_rsa)); 171 172 if(!p7_rsa->public_key_data) { 166 173 wi_release(p7_rsa); 167 174 168 175 return NULL; 169 176 } 170 171 p7_rsa->public_key_data = wi_data_init_with_bytes(wi_data_alloc(), buffer, length);172 173 OPENSSL_free(buffer);174 177 175 178 return p7_rsa; … … 225 228 #pragma mark - 226 229 230 static wi_data_t * _wi_p7_rsa_public_key_data(wi_p7_rsa_t *p7_rsa) { 231 wi_data_t *data; 232 unsigned char *buffer; 233 int length; 234 235 buffer = NULL; 236 length = i2d_RSA_PUBKEY(p7_rsa->rsa, &buffer); 237 238 if(length <= 0) { 239 wi_error_set_openssl_error(); 240 241 return NULL; 242 } 243 244 data = wi_data_with_bytes(buffer, length); 245 246 OPENSSL_free(buffer); 247 248 return data; 249 } 250 251 252 253 #pragma mark - 227 254 228 255 wi_data_t * wi_p7_rsa_public_key_data(wi_p7_rsa_t *p7_rsa) { … … 429 456 wi_p7_cipher_t *p7_cipher = instance; 430 457 431 return wi_string_with_format(WI_STR("<%@ %p>{ bits = %u}"),458 return wi_string_with_format(WI_STR("<%@ %p>{name = %@, bits = %u}"), 432 459 wi_runtime_class_name(p7_cipher), 433 460 p7_cipher, 434 EVP_CIPHER_key_length(&p7_cipher->cipher_ctx) * 8); 461 wi_p7_cipher_name(p7_cipher), 462 wi_p7_cipher_bits(p7_cipher)); 435 463 } 436 464 … … 474 502 #pragma mark - 475 503 504 wi_string_t * wi_p7_cipher_name(wi_p7_cipher_t *p7_cipher) { 505 return wi_string_with_cstring(EVP_CIPHER_name(p7_cipher->cipher)); 506 } 507 508 509 510 wi_uinteger_t wi_p7_cipher_bits(wi_p7_cipher_t *p7_cipher) { 511 return EVP_CIPHER_key_length(&p7_cipher->cipher_ctx) * 8; 512 } 513 514 515 516 #pragma mark - 517 476 518 wi_boolean_t wi_p7_cipher_encrypt_bytes(wi_p7_cipher_t *p7_cipher, const void *decrypted_buffer, wi_uinteger_t decrypted_length, void **out_buffer, wi_uinteger_t *out_length) { 477 519 void *encrypted_buffer; libwired/trunk/libwired/p7/wi-p7-crypto.h
r4627 r4629 49 49 50 50 WI_EXPORT wi_p7_rsa_t * wi_p7_rsa_alloc(void); 51 WI_EXPORT wi_p7_rsa_t * wi_p7_rsa_init_with_ size(wi_p7_rsa_t *, wi_uinteger_t);51 WI_EXPORT wi_p7_rsa_t * wi_p7_rsa_init_with_bits(wi_p7_rsa_t *, wi_uinteger_t); 52 52 WI_EXPORT wi_p7_rsa_t * wi_p7_rsa_init_with_pem_file(wi_p7_rsa_t *, wi_string_t *); 53 53 WI_EXPORT wi_p7_rsa_t * wi_p7_rsa_init_with_public_key_data(wi_p7_rsa_t *, wi_data_t *); … … 70 70 WI_EXPORT wi_data_t * wi_p7_cipher_iv_data(wi_p7_cipher_t *); 71 71 72 WI_EXPORT wi_string_t * wi_p7_cipher_name(wi_p7_cipher_t *); 73 WI_EXPORT wi_uinteger_t wi_p7_cipher_bits(wi_p7_cipher_t *); 74 72 75 WI_EXPORT wi_boolean_t wi_p7_cipher_encrypt_bytes(wi_p7_cipher_t *, const void *, wi_uinteger_t, void **, wi_uinteger_t *); 73 76 WI_EXPORT wi_data_t * wi_p7_cipher_encrypt_data(wi_p7_cipher_t *, wi_data_t *); … … 75 78 WI_EXPORT wi_data_t * wi_p7_cipher_decrypt_data(wi_p7_cipher_t *, wi_data_t *); 76 79 77 #endif /* WI_ ARRAY_H */80 #endif /* WI_P7_CRYPTO_H */ libwired/trunk/libwired/p7/wi-p7-message.h
r4623 r4629 110 110 WI_EXPORT wi_date_t * wi_p7_message_date_for_name(wi_p7_message_t *, wi_string_t *); 111 111 112 #endif /* WI_ ARRAY_H */112 #endif /* WI_P7_MESSAGE_H */ libwired/trunk/libwired/p7/wi-p7-private.h
r4623 r4629 66 66 WI_EXPORT wi_integer_t wi_p7_xml_integer_for_attribute(xmlNodePtr, wi_string_t *); 67 67 68 #endif /* WI_ ARRAY_H */68 #endif /* WI_P7_PRIVATE_H */ libwired/trunk/libwired/p7/wi-p7-socket.c
r4626 r4629 218 218 219 219 220 wi_p7_cipher_t * wi_p7_socket_cipher(wi_p7_socket_t *p7_socket) { 221 return p7_socket->cipher; 222 } 223 224 225 220 226 wi_p7_options_t wi_p7_socket_options(wi_p7_socket_t *p7_socket) { 221 227 return p7_socket->options; … … 240 246 p7_message = wi_p7_message_with_name(WI_STR("p7.handshake"), p7_socket); 241 247 242 if(!p7_message) 243 return false; 248 if(!p7_message) { 249 wi_log_info(WI_STR("couldn't create message")); 250 251 return false; 252 } 244 253 245 254 wi_p7_message_set_uint32_for_name(p7_message, WI_P7_VERSION, WI_STR("p7.handshake.version")); … … 308 317 p7_message = wi_p7_message_with_name(WI_STR("p7.handshake.acknowledge"), p7_socket); 309 318 310 if(!p7_message) 311 return false; 319 if(!p7_message) { 320 wi_log_info(WI_STR("couldn't create message")); 321 322 return false; 323 } 312 324 313 325 if(p7_socket->local_compatibility_check) … … 378 390 p7_message = wi_p7_message_with_name(WI_STR("p7.handshake.reply"), p7_socket); 379 391 380 if(!p7_message) 381 return false; 392 if(!p7_message) { 393 wi_log_info(WI_STR("couldn't create message")); 394 395 return false; 396 } 382 397 383 398 wi_p7_message_set_uint32_for_name(p7_message, WI_P7_VERSION, WI_STR("p7.handshake.version")); … … 430 445 p7_message = wi_p7_socket_read_message(p7_socket, timeout); 431 446 432 if(!p7_message) 433 return false; 447 if(!p7_message) { 448 wi_log_warn(WI_STR("couldn't read message")); 449 450 return false; 451 } 434 452 435 453 if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption"))) { … … 467 485 p7_message = wi_p7_message_with_name(WI_STR("p7.encryption.reply"), p7_socket); 468 486 469 if(!p7_message) 470 return false; 487 if(!p7_message) { 488 wi_log_info(WI_STR("couldn't create message")); 489 490 return false; 491 } 471 492 472 493 wi_p7_message_set_data_for_name(p7_message, wi_p7_cipher_key_data(p7_socket->cipher), WI_STR("p7.encryption.cipher_key")); … … 496 517 wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.client_password")); 497 518 498 if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) 499 return false; 519 if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) { 520 wi_log_warn(WI_STR("couldn't write message")); 521 522 return false; 523 } 500 524 501 525 p7_message = wi_p7_socket_read_message(p7_socket, timeout); 502 526 503 if(!p7_message) 504 return false; 527 if(!p7_message) { 528 wi_log_warn(WI_STR("couldn't read message")); 529 530 return false; 531 } 505 532 506 533 if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption.acknowledge"))) { … … 554 581 rsa_data = wi_p7_rsa_public_key_data(p7_socket->rsa); 555 582 556 if(!rsa_data) 557 return false; 583 wi_log_info(WI_STR("rsa_data = %@"), rsa_data); 558 584 559 585 p7_message = wi_p7_message_with_name(WI_STR("p7.encryption"), p7_socket); 560 586 561 if(!p7_message) 562 return false; 587 if(!p7_message) { 588 wi_log_info(WI_STR("couldn't create message")); 589 590 return false; 591 } 563 592 564 593 wi_p7_message_set_data_for_name(p7_message, rsa_data, WI_STR("p7.encryption.envelope_key")); 565 594 566 if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) 567 return false; 595 if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) { 596 wi_log_warn(WI_STR("couldn't write message")); 597 598 return false; 599 } 568 600 569 601 p7_message = wi_p7_socket_read_message(p7_socket, timeout); 570 602 571 if(!p7_message) 572 return false; 603 if(!p7_message) { 604 wi_log_info(WI_STR("couldn't create message")); 605 606 return false; 607 } 573 608 574 609 if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption.reply"))) { … … 593 628 iv_data); 594 629 595 if(!p7_socket->cipher) 596 return false; 630 if(!p7_socket->cipher) { 631 wi_log_warn(WI_STR("couldn't create cipher")); 632 633 return false; 634 } 597 635 598 636 data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.username")); … … 606 644 data = wi_p7_rsa_private_decrypt_data(p7_socket->rsa, data); 607 645 608 if(!data) 609 return false; 646 if(!data) { 647 wi_log_warn(WI_STR("couldn't rsa decrypt")); 648 649 return false; 650 } 610 651 611 652 username = wi_string_with_data(data); … … 621 662 data = wi_p7_rsa_private_decrypt_data(p7_socket->rsa, data); 622 663 623 if(!data) 624 return false; 664 if(!data) { 665 wi_log_warn(WI_STR("couldn't rsa decrypt")); 666 667 return false; 668 } 625 669 626 670 client_password = wi_string_with_data(data); … … 649 693 p7_message = wi_p7_message_with_name(WI_STR("p7.encryption.acknowledge"), p7_socket); 650 694 651 if(!p7_message) 652 return false; 695 if(!p7_message) { 696 wi_log_info(WI_STR("couldn't create message")); 697 698 return false; 699 } 653 700 654 701 data = wi_p7_cipher_encrypt_data(p7_socket->cipher, wi_string_data(server_password2)); 655 702 656 wi_log_info(WI_STR("crypted %@ with %@"), data, p7_socket->cipher); 657 658 if(!data) 659 return false; 703 if(!data) { 704 wi_log_warn(WI_STR("couldn't cipher encrypt")); 705 706 return false; 707 } 660 708 661 709 wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.server_password")); 662 710 663 if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) 664 return false; 711 if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) { 712 wi_log_warn(WI_STR("couldn't write message")); 713 714 return false; 715 } 665 716 666 717 p7_socket->encryption_enabled = true; … … 677 728 p7_message = wi_p7_message_with_name(WI_STR("p7.compatibility_check.specification"), p7_socket); 678 729 679 if(!p7_message) 680 return false; 730 if(!p7_message) { 731 wi_log_info(WI_STR("couldn't create message")); 732 733 return false; 734 } 681 735 682 736 wi_p7_message_set_string_for_name(p7_message, wi_p7_spec_xml(p7_socket->spec), WI_STR("p7.compatibility_check.specification")); … … 754 808 p7_message = wi_p7_message_with_name(WI_STR("p7.compatibility_check.status"), p7_socket); 755 809 756 if(!p7_message) 757 return false; 810 if(!p7_message) { 811 wi_log_info(WI_STR("couldn't create message")); 812 813 return false; 814 } 758 815 759 816 wi_p7_message_set_bool_for_name(p7_message, compatible, WI_STR("p7.compatibility_check.status")); … … 1121 1178 prefix = WI_STR("<?xm"); 1122 1179 } 1123 else if(length == _WI_P7_SOCKET_BINARY_MAGIC_LENGTH) {1180 else if(length <= _WI_P7_SOCKET_BINARY_MAGIC_LENGTH) { 1124 1181 p7_socket->serialization = WI_P7_BINARY; 1125 1182 } … … 1131 1188 else if(p7_socket->serialization == WI_P7_XML) 1132 1189 p7_message = _wi_p7_socket_read_xml_message(p7_socket, timeout, prefix); 1133 else 1134 p7_message = NULL; 1135 1136 if(!p7_message) 1190 else { 1191 wi_log_info(WI_STR("unknown serialization")); 1192 1137 1193 return NULL; 1194 } 1195 1196 if(!p7_message) { 1197 wi_log_info(WI_STR("unable to extract message")); 1198 1199 return NULL; 1200 } 1138 1201 1139 1202 wi_p7_message_deserialize(p7_message); libwired/trunk/libwired/p7/wi-p7-socket.h
r4623 r4629 65 65 WI_EXPORT wi_socket_t * wi_p7_socket_socket(wi_p7_socket_t *); 66 66 WI_EXPORT wi_p7_spec_t * wi_p7_socket_spec(wi_p7_socket_t *); 67 WI_EXPORT wi_p7_cipher_t * wi_p7_socket_cipher(wi_p7_socket_t *); 67 68 WI_EXPORT wi_p7_options_t wi_p7_socket_options(wi_p7_socket_t *); 68 69 WI_EXPORT wi_p7_serialization_t wi_p7_socket_serialization(wi_p7_socket_t *); … … 78 79 WI_EXPORT wi_p7_socket_password_provider_func_t *wi_p7_socket_password_provider; 79 80 80 #endif /* WI_ ARRAY_H */81 #endif /* WI_P7_SOCKET_H */ libwired/trunk/libwired/p7/wi-p7-spec.c
r4623 r4629 217 217 218 218 219 #define _WI_P7_SPEC_REPLY_ONE_OR_ZERO -1 220 #define _WI_P7_SPEC_REPLY_ZERO_OR_MORE -2 221 #define _WI_P7_SPEC_REPLY_ONE_OR_MORE -3 222 219 223 struct _wi_p7_spec_reply { 220 224 wi_runtime_base_t base; … … 226 230 227 231 static _wi_p7_spec_reply_t * _wi_p7_spec_reply_with_node(wi_p7_spec_t *, xmlNodePtr, _wi_p7_spec_transaction_t *); 232 static wi_string_t * _wi_p7_spec_reply_count(_wi_p7_spec_reply_t *); 228 233 static void _wi_p7_spec_reply_dealloc(wi_runtime_instance_t *); 229 234 static wi_string_t * _wi_p7_spec_reply_description(wi_runtime_instance_t *); … … 273 278 static wi_boolean_t _wi_p7_spec_transaction_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_transaction_t *); 274 279 static wi_boolean_t _wi_p7_spec_andor_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_andor_t *, _wi_p7_spec_andor_t *); 275 static wi_boolean_t _wi_p7_spec_reply_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_reply_t *, _wi_p7_spec_reply_t *); 280 static wi_boolean_t _wi_p7_spec_replies_are_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_andor_t *, _wi_p7_spec_andor_t *, wi_boolean_t); 281 static wi_boolean_t _wi_p7_spec_reply_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_reply_t *, _wi_p7_spec_reply_t *, wi_boolean_t); 276 282 static wi_boolean_t _wi_p7_spec_message_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_message_t *, _wi_p7_spec_message_t *); 277 283 … … 868 874 wi_boolean_t compatible; 869 875 870 compatible = (_wi_p7_spec_is_compatible(p7_spec, other_p7_spec) && _wi_p7_spec_is_compatible(other_p7_spec, p7_spec));876 compatible = _wi_p7_spec_is_compatible(p7_spec, other_p7_spec); 871 877 872 878 if(compatible) … … 914 920 915 921 if(other_transaction) { 916 if(!_wi_p7_spec_message_is_compatible(p7_spec, transaction, transaction->message, other_transaction->message))917 return false;918 919 922 if(transaction->originator != other_transaction->originator) { 920 923 _wi_p7_spec_log_debug(p7_spec, WI_STR("Transaction \"%@\" should be sent by %@, but peer sends it by %@"), … … 926 929 } 927 930 931 if(!_wi_p7_spec_message_is_compatible(p7_spec, transaction, transaction->message, other_transaction->message)) 932 return false; 933 928 934 if(!_wi_p7_spec_andor_is_compatible(p7_spec, transaction, transaction->andor, other_transaction->andor)) 929 935 return false; … … 936 942 937 943 static wi_boolean_t _wi_p7_spec_andor_is_compatible(wi_p7_spec_t *p7_spec, _wi_p7_spec_transaction_t *transaction, _wi_p7_spec_andor_t *andor, _wi_p7_spec_andor_t *other_andor) { 938 wi_enumerator_t *enumerator; 939 _wi_p7_spec_reply_t *reply, *other_reply, *each_reply; 940 wi_uinteger_t i, count, other_count, index; 944 wi_uinteger_t i, count, other_count; 945 946 if(andor->type != other_andor->type) 947 return false; 948 949 if(!_wi_p7_spec_replies_are_compatible(p7_spec, transaction, andor, other_andor, false) || 950 !_wi_p7_spec_replies_are_compatible(p7_spec, transaction, other_andor, andor, true)) 951 return false; 952 953 count = wi_array_count(andor->children); 954 other_count = wi_array_count(other_andor->children); 955 956 if(count != other_count) { 957 _wi_p7_spec_log_debug(p7_spec, WI_STR("Transaction \"%@\" should have %u %@, but peer has %u"), 958 transaction->message->name, 959 count, 960 count == 1 961 ? WI_STR("child") 962 : WI_STR("children"), 963 other_count); 964 965 return false; 966 } 967 968 for(i = 0; i < count; i++) { 969 if(!_wi_p7_spec_andor_is_compatible(p7_spec, transaction, WI_ARRAY(andor->children, i), WI_ARRAY(other_andor->children, i))) 970 return false; 971 } 972 973 return true; 974 } 975 976 977 978 static wi_boolean_t _wi_p7_spec_replies_are_compatible(wi_p7_spec_t *p7_spec, _wi_p7_spec_transaction_t *transaction, _wi_p7_spec_andor_t *andor, _wi_p7_spec_andor_t *other_andor, wi_boolean_t commutativity) { 979 wi_enumerator_t *enumerator; 980 _wi_p7_spec_reply_t *reply, *other_reply, *each_reply; 981 wi_uinteger_t i, count, index; 941 982 942 983 if(andor->type != other_andor->type) … … 963 1004 index = i + 1; 964 1005 965 if( other_reply && !_wi_p7_spec_reply_is_compatible(p7_spec, transaction, reply, other_reply))1006 if(!_wi_p7_spec_reply_is_compatible(p7_spec, transaction, reply, other_reply, commutativity)) 966 1007 return false; 967 1008 } else { 968 1009 other_reply = wi_hash_data_for_key(other_andor->replies_hash, reply->message->name); 969 1010 970 if(!_wi_p7_spec_reply_is_compatible(p7_spec, transaction, reply, other_reply ))1011 if(!_wi_p7_spec_reply_is_compatible(p7_spec, transaction, reply, other_reply, commutativity)) 971 1012 return false; 972 1013 } 973 1014 } 974 1015 975 count = wi_array_count(andor->children);976 other_count = wi_array_count(other_andor->children);977 978 if(count != other_count) {979 _wi_p7_spec_log_debug(p7_spec, WI_STR("Transaction \"%@\" should have %u %@, but peer has %u"),980 transaction->message->name,981 count,982 count == 1983 ? WI_STR("child")984 : WI_STR("children"),985 other_count);986 987 return false;988 }989 990 for(i = 0; i < count; i++) {991 if(!_wi_p7_spec_andor_is_compatible(p7_spec, transaction, WI_ARRAY(andor->children, i), WI_ARRAY(other_andor->children, i)))992 return false;993 }994 995 1016 return true; 996 1017 } … … 998 1019 999 1020 1000 static wi_boolean_t _wi_p7_spec_reply_is_compatible(wi_p7_spec_t *p7_spec, _wi_p7_spec_transaction_t *transaction, _wi_p7_spec_reply_t *reply, _wi_p7_spec_reply_t *other_reply) { 1021 static wi_boolean_t _wi_p7_spec_reply_is_compatible(wi_p7_spec_t *p7_spec, _wi_p7_spec_transaction_t *transaction, _wi_p7_spec_reply_t *reply, _wi_p7_spec_reply_t *other_reply, wi_boolean_t commutativity) { 1022 wi_boolean_t compatible; 1023 1001 1024 if(reply->required) { 1002 1025 if(!other_reply || !other_reply->required) { … … 1013 1036 } 1014 1037 1015 if(other_reply) { 1016 if(reply->count != other_reply->count) { 1017 _wi_p7_spec_log_debug(p7_spec, WI_STR("Reply \"%@\" in transaction \"%@\" should be sent %u %@, but peer sends it %u %@"), 1018 reply->message->name, 1019 reply->count, 1020 reply->count == 1 1021 ? WI_STR("time") 1022 : WI_STR("times"), 1023 other_reply->count, 1024 other_reply->count == 1 1025 ? WI_STR("time") 1026 : WI_STR("times")); 1027 1028 return false; 1029 } 1030 1031 if(!_wi_p7_spec_message_is_compatible(p7_spec, transaction, reply->message, other_reply->message)) 1032 return false; 1038 if(!commutativity) { 1039 if(other_reply) { 1040 if(reply->count == _WI_P7_SPEC_REPLY_ONE_OR_ZERO) 1041 compatible = (other_reply->count == _WI_P7_SPEC_REPLY_ONE_OR_ZERO); 1042 else if(reply->count == _WI_P7_SPEC_REPLY_ZERO_OR_MORE) 1043 compatible = (other_reply->count == _WI_P7_SPEC_REPLY_ONE_OR_ZERO || other_reply->count == _WI_P7_SPEC_REPLY_ZERO_OR_MORE); 1044 else if(reply->count == _WI_P7_SPEC_REPLY_ONE_OR_MORE) 1045 compatible = (other_reply->count == _WI_P7_SPEC_REPLY_ONE_OR_MORE || other_reply->count > 0); 1046 else 1047 compatible = (reply->count == other_reply->count); 1048 1049 if(!compatible) { 1050 _wi_p7_spec_log_debug(p7_spec, WI_STR("Reply \"%@\" in transaction \"%@\" should be sent %@, but peer sends it %@"), 1051 reply->message->name, 1052 transaction->message->name, 1053 _wi_p7_spec_reply_count(reply), 1054 _wi_p7_spec_reply_count(other_reply)); 1055 1056 return false; 1057 } 1058 1059 if(!_wi_p7_spec_message_is_compatible(p7_spec, transaction, reply->message, other_reply->message)) 1060 return false; 1061 } 1033 1062 } 1034 1063 … … 1043 1072 _wi_p7_spec_parameter_t *parameter, *other_parameter; 1044 1073 _wi_p7_spec_field_t *field, *other_field; 1074 1075 if(!wi_is_equal(message->name, other_message->name)) { 1076 _wi_p7_spec_log_debug(p7_spec, 1077 WI_STR("Reply in transaction \"%@\" should be \"%@\", but peer has \"%@\""), 1078 transaction->message->name, message->name, other_message->name); 1079 1080 return false; 1081 } 1045 1082 1046 1083 if(message->id != other_message->id) { … … 1789 1826 static _wi_p7_spec_reply_t * _wi_p7_spec_reply_with_node(wi_p7_spec_t *p7_spec, xmlNodePtr node, _wi_p7_spec_transaction_t *transaction) { 1790 1827 _wi_p7_spec_reply_t *reply; 1791 wi_string_t *message, *use ;1828 wi_string_t *message, *use, *count; 1792 1829 1793 1830 reply = wi_autorelease(wi_runtime_create_instance(_wi_p7_spec_reply_runtime_id, sizeof(_wi_p7_spec_reply_t))); … … 1828 1865 reply->required = (wi_string_case_insensitive_compare(use, WI_STR("required")) == 0); 1829 1866 } 1830 1831 reply->count = wi_p7_xml_integer_for_attribute(node, WI_STR("count")); 1867 1868 count = wi_p7_xml_string_for_attribute(node, WI_STR("count")); 1869 1870 if(!count) { 1871 _wi_p7_spec_log_debug(p7_spec, WI_STR("Reply in transaction \"%@\" has no \"count\""), 1872 transaction->message->name); 1873 1874 return NULL; 1875 } 1876 1877 if(wi_string_compare(count, WI_STR("?")) == 0) 1878 reply->count = _WI_P7_SPEC_REPLY_ONE_OR_ZERO; 1879 else if(wi_string_compare(count, WI_STR("*")) == 0) 1880 reply->count = _WI_P7_SPEC_REPLY_ZERO_OR_MORE; 1881 else if(wi_string_compare(count, WI_STR("+")) == 0) 1882 reply->count = _WI_P7_SPEC_REPLY_ONE_OR_MORE; 1883 else 1884 reply->count = wi_string_integer(count); 1885 1886 if(reply->count == 0) { 1887 _wi_p7_spec_log_debug(p7_spec, WI_STR("Reply in transaction \"%@\" has an invalid \"count\" (\"%@\")"), 1888 transaction->message->name, count); 1889 1890 return NULL; 1891 } 1832 1892 1833 1893 return reply; 1894 } 1895 1896 1897 1898 static wi_string_t * _wi_p7_spec_reply_count(_wi_p7_spec_reply_t *reply) { 1899 if(reply->count == _WI_P7_SPEC_REPLY_ONE_OR_ZERO) 1900 return WI_STR("one or zero times"); 1901 if(reply->count == _WI_P7_SPEC_REPLY_ZERO_OR_MORE) 1902 return WI_STR("zero or more times"); 1903 else if(reply->count == _WI_P7_SPEC_REPLY_ONE_OR_MORE) 1904 return WI_STR("one or more times"); 1905 1906 return wi_string_with_format(WI_STR("%u %@"), reply->count, (reply->count == 1) ? WI_STR("time") : WI_STR("times")); 1834 1907 } 1835 1908 libwired/trunk/libwired/p7/wi-p7-spec.h
r4623 r4629 62 62 WI_EXPORT wi_p7_enum_t wi_p7_spec_enum_value(wi_p7_spec_t *, wi_integer_t, wi_string_t *); 63 63 64 #endif /* WI_ ARRAY_H */64 #endif /* WI_P7_SPEC_H */
