+
+krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
+ void *data,
+ krb5_krbhst_info *hi,
+ time_t timeout,
+ const krb5_data *send_buf,
+ krb5_data *recv_buf)
+{
+ krb5_error_code ret;
+ struct addrinfo *ai;
+
+ struct tevent_context *ev;
+ TALLOC_CTX *frame = talloc_stackframe();
+ if (frame == NULL) {
+ return ENOMEM;
+ }
+
+ if (data == NULL) {
+ /* If no event context was available, then create one for this loop */
+ ev = samba_tevent_context_init(frame);
+ if (ev == NULL) {
+ TALLOC_FREE(frame);
+ return ENOMEM;
+ }
+ } else {
+ ev = talloc_get_type_abort(data, struct tevent_context);
+ }
+
+ ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
+ if (ret) {
+ TALLOC_FREE(frame);
+ return ret;
+ }
+
+ ret = smb_krb5_send_and_recv_func_int(context, ev, hi, ai, smb_krb5_send_and_recv_func, data, timeout, send_buf, recv_buf);
+ TALLOC_FREE(frame);
+ return ret;
+}
+
+krb5_error_code smb_krb5_send_and_recv_func_forced(krb5_context context,
+ void *data, /* struct addrinfo */
+ krb5_krbhst_info *hi,
+ time_t timeout,
+ const krb5_data *send_buf,
+ krb5_data *recv_buf)
+{
+ krb5_error_code k5ret;
+ struct addrinfo *ai = data;
+
+ struct tevent_context *ev;
+ TALLOC_CTX *frame = talloc_stackframe();
+ if (frame == NULL) {
+ return ENOMEM;
+ }
+
+ /* no event context is passed in, create one for this loop */
+ ev = samba_tevent_context_init(frame);
+ if (ev == NULL) {
+ TALLOC_FREE(frame);
+ return ENOMEM;
+ }
+
+ /* No need to pass in send_and_recv functions, we won't nest on this private event loop */
+ k5ret = smb_krb5_send_and_recv_func_int(context, ev, hi, ai, NULL, NULL,
+ timeout, send_buf, recv_buf);
+ TALLOC_FREE(frame);
+ return k5ret;
+}